home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 60.zip / BS1 part 60 / LSD 32.adf / AmigaGfx1.pp / AmigaGfx1
Text File  |  1990-09-07  |  184KB  |  4,921 lines

  1.  _________________________________________________________________________
  2. /#########################################################################\
  3. |#####...####..######..######......####...####..#####..##......##......###|
  4. |####.....###..######..########..#####.....###...####..##..######..#######|
  5. |###..###..##..######..########..####..###..##....###..##..######..#######|
  6. |###..###..##..######..########..####..###..##..#...#..##..######......###|
  7. |###.......##..######..########..####.......##..##.....##..######..#######|
  8. |###..###..##..######..########..####..###..##..###....##..######..#######|
  9. |###..###..##...#####...#######..####..###..##..####...##..######..#######|
  10. |###..###..##......##......##......##..###..##..#####..##......##......###|
  11. |#########################################################################|
  12. |####################################################################{RB}#|
  13. |=========================================================================|
  14. |                                      |
  15. |                   ----> PRESENTS <----                  |
  16. |                                      |
  17. |            AMIGA GRAPHICS INSIDE AND OUT - THE COMPLETE BOOK            |
  18. |                                      |
  19. |                               > PART 1 <                                |
  20. |                                                                         |
  21. | Typed / Scanned / Edited By : RAZOR BLADE.                      |
  22. | Additional Typing by        : GLITCH ( + 8 pages by Asterix ! ).      |
  23. | Original Supplied by          : VIPER                      |
  24. |                                      |
  25. |-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|
  26. |         CALL THE ALLIANCE WORLD HQ -> THE PLACE TO BE             |
  27. |       UNKNOWN PLEASURES --> +44 (0) 823 322 891 --> SYSOP: BARBARIAN    |
  28. |_________________________________________________________________________|
  29.  
  30.  
  31.                         TABLE OF CONTENTS.
  32.  
  33. Introduction                                                    ix
  34. 1.      Amiga Graphics                                          1
  35. 1.1     Setting pixels with PSET                                1
  36. 1.1.1   Using the mouse and PSET:a simple drawing board         1
  37. 1.1.2   Rosette and Garland Patterns                            2
  38. 1.1.3   Erasing Pixels                                          3
  39. 1.1.4   Adding colour to your screen                            4
  40. 1.1.5   More about PSET and PRESET                              6
  41. 1.1.6   The opposite of PSET: the POINT statement               7
  42. 1.1.7   Relative Addressing                                     8
  43. 1.2     The LINE statement                                      10
  44. 1.2.1   The power of LINE                                       10
  45. 1.2.2   The Moire effect                                        10
  46. 1.2.3   Quix, Lines galore                                      11
  47. 1.2.4   Function Plotter                                        12
  48. 1.2.4.1 Function Plotter modes and menu controls                15
  49. 1.2.4.2 Undefined function values                               16
  50. 1.2.4.3 Scaling                                                 16
  51. 1.2.5   Drawing Rectangles                                      17
  52. 1.2.6   Relative addressing with the LINE statement             18
  53. 1.3     The CIRCLE statement                                    20
  54. 1.3.1   The aspect ratio                                        20
  55. 1.3.1.1 Animation using CIRCLE                                  21
  56. 1.3.1.2 The aspect ratio in circle formulas                     23
  57. 1.3.2   Angle parameters with CIRCLE                            24
  58. 1.3.3   Relative addressing with CIRCLE                         25
  59. 1.3.4   Pie Charts                                              25
  60. 1.3.5   Pixels and lines with CIRCLE                            27
  61. 1.4     Area fill                                               30
  62. 1.4.1   The PAINT statement                                     30
  63. 1.4.2   Another solution: AREA and AREAFILL                     31
  64. 1.4.2.1 Different modes of AREAFILL                             33
  65. 1.4.3   Patterns                                                34
  66. 1.4.3.1 Pattern Creation                                        34
  67. 1.4.3.2 Patterned Areas                                         35
  68. 1.4.3.3 Pattern Design in a program                             36
  69. 1.4.3.4 Patterns and the Cursor                                 38
  70. 1.4.3.5 Bringing it together                                    39
  71. 1.5     Medley of colours                                       41
  72. 1.5.1   The complete palette                                    42
  73. 1.5.2   changing RGB colours                                    42
  74.  
  75.                                 PAGE iii
  76.  
  77. ----------------------------------------------------------------------------
  78.  
  79. 1.5.3   The opposite of PALETTE                                 43
  80. 1.5.4   Animation using color                                   44
  81. 1.6     All about PUT and GET                                   46
  82. 1.6.1   Using PUT and GET                                       46
  83. 1.6.2   Saving to Disk                                          48
  84. 1.6.3   Alternate uses for PUT                                  50
  85. 1.6.3.1 Default mode of PUT                                     50
  86. 1.6.3.2 A direct method using PSET                              52
  87. 1.6.3.3 Inverting graphics                                      52
  88. 1.6.3.4 AND or OR                                               53
  89. 1.7     Animation in BASIC                                      55
  90. 1.7.1   Sprites and bobs                                        55
  91. 1.7.2   The OBJECT.SHAPE statement                              56
  92. 1.7.3   Designing an object                                     56
  93. 1.7.4   The complete object editor: Eddi II                     56
  94. 1.7.4.1 The screen                                              68
  95. 1.7.4.2 Object size                                             68
  96. 1.7.4.3 Depth                                                   69
  97. 1.7.4.4 Colors                                                  69
  98. 1.7.4.5 Drawing                                                 69
  99. 1.7.4.6 Loading and Saving                                      71
  100. 1.7.4.7 Testing Objects                                         71
  101. 1.7.4.8 Exiting Eddi II                                         71
  102. 1.7.4.9 Loading objects into your programs                      72
  103. 1.7.5   Flags                                                   72
  104. 1.7.5.1 The SaveBack flag                                       72
  105. 1.7.5.2 SaveBob                                                 75
  106. 1.7.5.3 Overlay                                                 75
  107. 1.7.5.4 The shadow mask                                         75
  108. 1.7.5.5 Collisions                                              76
  109. 1.7.5.6 Animated bit-planes                                     80
  110. 1.7.6   The alternative: sprites                                85
  111. 1.7.6.1 The small difference                                    85
  112. 1.7.6.2 Color and Sprites                                       85
  113.  
  114. 2.      The amiga operating system                              87
  115.  
  116. 3.      Intuition - the user interface                          93
  117. 3.1     Intuition windows                                       93 
  118. 3.2     The window data structure                               96
  119. 3.3     Functions of the intuition library                      106
  120. 3.3.1   A personalised mouse pointer                            106
  121. 3.3.2   Moving windows made easy                                109
  122. 3.3.3   Setting Window Limits                                   110
  123. 3.3.4   Sizing Windows                                          111
  124. 3.3.5   WindowToFront and WindowToBack                          113
  125.  
  126.                                 PAGE iv
  127.  
  128. ----------------------------------------------------------------------------
  129.  
  130. 3.4     The Intuition Screen                                    114
  131. 3.4.1   Screen Structure                                        115
  132. 3.4.2   The Intuition functions for screen handling             118
  133. 3.5     Intuition and the rest of the world                     120
  134. 3.6     The RastPort                                            122
  135. 3.6.1   RastPort data structure.                                123
  136. 3.7     Graphic Primitives                                      129
  137. 3.7.1   Multi-colour patterns                                   129
  138. 3.7.2   Shadows using Cursor positioning                        140
  139. 3.7.3   Outline print - a special flair.                        143
  140. 3.7.4   Text Styles                                             144
  141. 3.8     The RastPort and the graphic system                     148
  142. 3.9     The Bit-Map structure                                   149
  143.  
  144. 4.      The ViewPort                                            151
  145. 4.1     The ViewPort data structure                             153
  146. 4.2     The graphic modes of the Amiga                          155
  147. 4.2.1   The Halfbrite mode                                      156
  148. 4.2.2   The hold-and-modify mode: 4096 colours                  161
  149. 4.3     The ViewPort in the system                              166
  150. 4.4     View: The graphic brain                                 168
  151. 4.5     Copper Programming                                      175
  152. 4.5.1   Double buffering for lightening fast graphics           175
  153. 4.5.2   Programming the Copper yourself                         180
  154. 4.5.3   Programming 400 simultaneous colours                    185
  155. 4.6     The Layers : Soul of the windows                        188
  156. 4.6.1   The Layer data structure                                191
  157. 4.7     The different layer types                               196
  158. 4.7.1   Simple Layers: your own requester                       197
  159. 4.7.2   The superlayer: 1024 * 1024 pixels                      199
  160. 4.7.3   Permanently deactivating layers                         205
  161. 4.7.4   Using the BASIC commands within a layer                 206
  162. 4.8     Layers in the system                                    212
  163.  
  164. 5       The Amiga fonts                                         213
  165. 5.1     The Amiga character generator                           214
  166. 5.2     Opening your first font                                 218
  167. 5.3     Accessing the disk fonts                                221
  168. 5.4     The font menu                                           228
  169. 5.5     Designing your own fonts                                234
  170. 5.5.1   Reading the font generator                              236
  171. 5.5.2   Big text: enlarging text                                240
  172. 5.5.3   A fixed width font generator                            243
  173. 5.5.4   A proportional font                                     252
  174.  
  175.                                 Page v
  176.  
  177. ----------------------------------------------------------------------------
  178.  
  179. 6.      Graphic Hardcopy                                        259
  180. 6.1     A simple hardcopy routine                               262
  181. 6.2     Hardcopies: enlarging and shrinking                     265
  182. 6.3     Printing selected windows                               268
  183. 6.4     ScreenDump - the complete screen                        271
  184. 6.5     Multitasking hardcopy                                   274
  185.  
  186. 7.      The IFF-ILBM standard                                   279
  187.  
  188. 8.      A 1024*1024 Paint program                               293
  189. 8.1     Paint-1024 program instructions                         311
  190.  
  191. 9.      Graphic programming in C.                               315
  192. 9.1     The Amiga libraries                                     316
  193. 9.2     The boss: The view                                      317
  194. 9.3     The foreman: ViewPort                                   317
  195. 9.4     The worker: Bit-Map                                     319
  196. 9.5     The messenger: Rasinfo                                  322
  197. 9.6     The laborer: RastPort                                   323
  198. 9.7     Finish the day:                                         325
  199.  
  200. 10.     Lines and pixels                                        327
  201. 10.1    Pixels set with Writepixel                              327
  202. 10.2    Drawing lines with move and draw                        332
  203.  
  204. 11.     Colour: Drawing pens                                    339
  205. 11.1    The Drawmodes                                           340
  206. 11.2    The foreground pen                                      341
  207. 11.3    The background pen                                      341
  208.  
  209. 12.     Intuition and graphics                                  343
  210. 12.1    The individual screen                                   344
  211. 12.2    The Window                                              345
  212. 12.3    Exiting Intuition                                       345
  213.  
  214. 13.     Filling areas in C.                                     347
  215. 13.1    A flood function                                        347
  216. 13.2    Filling rectangles                                      349
  217. 13.3    Polygon filling: Area, makes it possible                356
  218.  
  219. 14.     The Colormap functions                                  381
  220. 14.1    Setting a new colour palette                            382
  221. 14.2    Changing one colour                                     382
  222. 14.3    Available colours                                       383
  223. 14.4    The pixels colour                                       386
  224.  
  225.                                 PAGE vi
  226.  
  227. ----------------------------------------------------------------------------
  228.  
  229. 15.     Text output                                             387
  230. 15.1    The text length                                         389
  231. 15.2    Fonts with the Amiga                                    389
  232. 15.3    Opening fonts                                           390
  233. 15.4    Closing the font                                        391
  234. 15.5    Software controlled text styles                         392
  235. 15.6    Fonts a la carte                                        393
  236.  
  237. 16.     The Blitter functions                                   399
  238. 16.1    Clearing a memory area                                  399
  239. 16.2    Copying data with the Blitter                           400
  240. 16.2.1  The ClipBit function                                    402
  241. 16.3    Reading data with the Blitter                           407
  242.  
  243. 17.     Amiga resolution modes                                  413
  244. 17.1    The resolution modes                                    414
  245. 17.2    The color modes                                         418
  246. 17.2.1  The EXTRA_HALFBRITE mode                                418
  247. 17.3    The special modes                                       422
  248. 17.3.1  Dual Playfield                                          422
  249. 17.3.2  Double buffering                                        423
  250. 17.4    Other modes                                             435
  251. 17.4.1  VP_HIDE                                                 435
  252. 17.4.2  Sprites                                                 435
  253. 17.4.2.1 The hardware sprites                                   435
  254. 17.4.2.2 Hardware sprites in 15 colours                         439
  255. 17.4.2.3 Sprite collisions                                      440
  256.  
  257. 18.     The Amiga animation system                              451
  258. 18.1    Vsprites                                                451
  259. 18.1.1  Vsprites and collisions                                 455
  260. 18.2    Another GEL: the bob                                    465
  261. 18.2.1  Bobs in buffered bit-maps                               476
  262. 18.3    AnimObs and AnimComps                                   479
  263. 18.3.1  Collisions with AnimObs                                 484
  264.  
  265. 19.     Copper programming in C                                 495
  266.  
  267. Appendices:
  268.  
  269. A:      Structure and include files                             503
  270. B:      The library-functions                                   527
  271. C:      The hardware                                            557
  272. Index                                                           593
  273.  
  274.                                 page vii
  275.  
  276. ----------------------------------------------------------------------------
  277.  
  278.                                 INTRODUCTION
  279.  
  280. The graphics powers of the Amiga are fantastic. You have probably seen many
  281. examples of Amiga graphics that overwhelm competing computers. How can you
  282. take command of this wonderful machine? How do you create your own graphics
  283. programs and understand what is going on inside your Amiga?.
  284.  
  285. The answers to these and hundreds of other questions are in this book. We
  286. will present the material so that it will interesting for both beginners
  287. and experienced programmers.
  288.  
  289. In chapter 1 we gently introduce the beginner to the amazing graphic world
  290. of the Amiga. Here you will learn first hand how to create graphics.
  291. Heavily documented BASIC programs demonstrate the use of the BASIC graphic
  292. statements and how to design and use moveable objects etc..
  293.  
  294. Experienced programmers will find chapters 2 thru 8 a step by step of the
  295. Amiga's multitasking graphics envoironment. We'll introduce you to the
  296. multitude of system graphic routines in the Kickstart-ROM. We discuss in
  297. detail, with tables, all data structures (window, screen, Viewport and
  298. more) At the end of this section you will be able to use graphics in 64
  299. color, halfbrite or 4096 HAM mode. You will also be capable of programming
  300. a coprocessor and other tasks that were not thought possible in BASIC.
  301.  
  302. In chapters 9 thru 19, we will examine the use of windows and screens using
  303. the C language, unveiling many system secrets. Last we enter the exiting
  304. world of automated animation, bobs, sprites and our own virtual sprite
  305. machine. Much of the information covered in this section is not even in the
  306. ROM manuals from Commodore!
  307.  
  308. Whether you use this book as an introduction to graphics or for solving a
  309. particular problem, you will find the contents of this book to be a wealth
  310. of grpahics information.
  311.  
  312. Weltner, Trapp, Jenrich (The authors)
  313. Razor Blade, Chaos, Mit, Viper, Shadowfax, Alchemist (The pirates!).
  314.  
  315.                                 PAGE ix
  316.  
  317. ----------------------------------------------------------------------------
  318.  
  319.                         CHAPTER 1 - AMIGA GRAPHICS.
  320.  
  321. In many ways the Amiga is a very unusual computer. Its excellent features
  322. have convinced not only graphics users, but many others that it is the
  323. computer for them.
  324.  
  325. The Amiga repeatedly surprises and fascinated users by the speed of its
  326. graphics, even graphics done in BASIC. Whether your graphics are very
  327. complex or only a small part of your BASIC program, there are several easy
  328. statements for drawing pixels, lines and circles.
  329.  
  330. A major difference between the Amiga and other computers is that you
  331. display text and Hi-resolution graphics on the same screen. The means that
  332. you can easily mix text and graphics without opening another screen. You
  333. can start experimenting with the graphic statements immediately.
  334.  
  335.                 -----------------------------------------------
  336.  
  337. 1.1 SETTING PIXELS WITH PSET.
  338.  
  339. The smallest unit in graphics is the PIXEL. We create all computer graphics
  340. from a full screen to single lines and pixels, by joining many small screen
  341. pixels. The statement you use to set pixels is short and simple:
  342.  
  343.         pset(10,20)
  344.  
  345. This example sets a pixel at a point 11 (10+1) from the left and 21 (20+1)
  346. down from the top of the window. Please note that pixel addressing, when
  347. referring to screen positions, starts with the value zero (0) and not one
  348. (1).
  349.  
  350.                         --------------------------------
  351.  
  352. 1.1.1 USING THE MOUSE AND PSET: A SIMPLE DRAWING BOARD.
  353.  
  354. Using the statement PSET you can set any desired point within the limits of
  355. the specified output window. The following program is a good example of
  356. this. Each time you click the left mouse button you will set a pixel on the
  357. screen where the point of the mouse pointer is located ( a pixel at the
  358. tip of the pointer).
  359.  
  360.                                 PAGE 1
  361.  
  362. ----------------------------------------------------------------------------
  363.  
  364. This is a very primitive drawing program, but we will use this principle to
  365. create a complete paint program.
  366.  
  367.         REM 1.1.1 Drawing with the mouse.       
  368.         PRINT "Now you can draw with the mouse"
  369.         WHILE INKEY$ = ""
  370.         IF MOUSE(0) <> 0 THEN
  371.            X = MOUSE(1)
  372.            Y = MOUSE(2)
  373.            PSET(X,Y)
  374.         END IF
  375.         WEND
  376.  
  377. As you can see, you need very few program lines for this small drawing
  378. program. The MOUSE function provides control of the mouse. When you click
  379. the left mouse button MOUSE(0) is not equal to zero. Now we can determine
  380. the mouse co-ordinates using MOUSE(1) for the X position and MOUSE(2) for
  381. the Y position.
  382.  
  383.                         -----------------------------------
  384.  
  385. 1.1.2 ROSETTE AND GARLAND PATTERNS.
  386.  
  387. You can create beautiful graphics using only the PSET statement. As you
  388. have just seen, you can draw them yourself, or you can let the computer
  389. create them for you. To have the computer generate you graphics you have to
  390. construct your statements so that the computer will understand what you
  391. want. To do this, you put your ideas into mathematical formulas. The
  392. following program generates different rosette patterns on the screen using
  393. formulas.
  394.  
  395.         REM 1.1.2 Rosette
  396.         pi=3.1415296#
  397.         f = .5 ' specifies the relation of height and width
  398.         INPUT "How many edges : ",edges
  399.         CLS     
  400.         IF edges <> - 1 THEN edges = edges + 1
  401.         REM predetermined values
  402.         radius = 100 ' Radius of maximum circle
  403.         inside = 3 ' Count of "inside" lines
  404.         outside = 3 ' Count of "outside" lines
  405.         FOR t = -inside/10 TO outside/10 STEP .1
  406.             FOR angle = 0 to 2*pi STEP .01
  407.                 x = radius * COS(angle)+t*radius*COS(angle*edges)
  408.                 y = radius * SIN(angle)+t*radius*SIN(angle*edges)
  409.                 PSET(300+x,y*f+100)
  410.             NEXT angle
  411.         NEXT t
  412.  
  413.                                 PAGE 2
  414.  
  415. ----------------------------------------------------------------------------
  416.  
  417. You can determine the shape of the rosette by entering different values for
  418. edges. Values between two and twenty work best, however negative numbers
  419. will also generate quite interesting images.
  420.  
  421. You can also modify the figures you created by experimenting with the
  422. program variables.
  423.  
  424. What you eventually see on screen is a design formed by many ellipsoids
  425. that are connected together. Ellipsoid simply means a series of curves
  426. generated by rolling an ellipse around one of its axis points. We do not
  427. draw the ellipse itself, only the outermost path of the curve. You can see
  428. this path as we plot it on the screen. The complete ellipsoidal formula can
  429. be found in any mathematics reference guide. We have changed it slightly to
  430. make it more user friendly.
  431.  
  432.                         ------------------------------
  433.  
  434. 1.1.3 ERASING PIXELS.
  435.  
  436. Since you can set the pixels, you must be able to erase them. In AmigaBASIC
  437. this procedure is very similar to setting the pixels, in fact the statement
  438. sounds almost the same. This statement has the same syntax as PSET and is:
  439.  
  440.         PRESET (x,y)
  441.  
  442. As you can see the only difference between the two statements is two
  443. letters. In a program it looks like this:
  444.  
  445.         REM 1.1.2 Demo for PRESET
  446.         a = 200
  447.         b = 400
  448.         c = 1
  449.         loop:
  450.           FOR x=a TO b STEP c
  451.              PSET(x,100)
  452.              PRESET(x-40*c,100)
  453.           NEXT x
  454.           SWAP a,b
  455.           c = -c
  456.         GOTO loop
  457.  
  458. In this program a 40 pixels long line appears to be moving back and forth
  459. on the screen. What exactly happens is that we add a new pixel to the
  460. beginning of the line and erase one from the end. To exit the program,
  461. press and hold the <CONTROL> key, then press the <C> key.
  462.  
  463.                                 PAGE 3
  464.  
  465. ----------------------------------------------------------------------------
  466.  
  467. 1.1.4 ADDING COLOUR TO YOUR SCREEN.
  468.  
  469. The previous programs have not really been a challenge for the Amiga. We
  470. could easily transfer these programs to other computers, although this does
  471. not apply to all programs. For example, when it comes to the use of colors,
  472. the amiga is unique. There are very few computers that can clain a palette
  473. of 4096 colours. We will begin by showing you how to use a 32 colour
  474. palette and later advance to 64 and even 4096 colours. You can set coloured
  475. pixels in the same way you previously set pixels, with the PSET statement.
  476. The only difference is that you must add, at the end of the statement, the
  477. value of the colour for a colour register:
  478.  
  479.         PSET(10,20),2
  480.  
  481. In this example, we determine the colour of the pixel from the second
  482. colour register. The default colour always starts with black so this pixel
  483. will be black.
  484.  
  485. If you now attempted to access the other 32 color registers (numbered 0 -
  486. 31) you would have problems. By the fifth or higher register value, the
  487. computer would display an error message. Why? Because we do not use all 32
  488. colours for every screen, the Amiga automatically saves memory by not
  489. assigning memory for these colours. The more colours you use, the more
  490. memory you requires (more on this later).
  491.  
  492. First, we have to open a new screen (one that exists at the same time as
  493. the workbench screen and is either behind it or covered by it). When you
  494. open a new screen you can specify parameters such as width, height, mode
  495. and colour depth. For depth you can use values between 1 and 5, certain
  496. screen modes only allow a maximum of 4. The following formula calculates
  497. the number of colours: 2 to the power of depth (2**depth). When you select
  498. a mode, you set the resolution of the screen. There are four possible
  499. modes on NTSC video systems:
  500.         
  501.         MODES           RESOLUTION
  502.         -----           ----------
  503.          1               320*200
  504.          2               640*200
  505.          3               320*400
  506.          4               640*400
  507.  
  508. PAL systems, available in Europe, contain 256 screen lines. In most of our
  509. programs we use mode one. Please note that the width and height of the
  510. screen cannot be greater than the values of the resolution mode selected.
  511.  
  512.                                 PAGE 4
  513.  
  514. ----------------------------------------------------------------------------
  515.  
  516. Nothing can be sent directly to a screen. Once we open a screen we must
  517. also open a window for it. This window is where all text and graphics will
  518. appear.
  519.  
  520.         REM 1.1.4A 32-color DEMO
  521.  
  522.         REM open a screen
  523.         SCREEN 1,320,200,5,1
  524.         REM open a window
  525.         WINDOW 2,"Colourpot",(0,0)-(311,185),16,1
  526.  
  527.         FOR y = 0 TO 186
  528.           FOR x = 0 TO 311
  529.              PSET (x,y),(x+y) MOD 32
  530.           NEXT x
  531.         NEXT y
  532.  
  533.         WHILE INKEY$ = "": WEND
  534.  
  535.         REM close window first, then screen
  536.         WINDOW CLOSE 2
  537.         SCREEN CLOSE 1
  538.  
  539. On the screen you will see all 32 possible colours. At the end of the
  540. program we close the window and screen, since they are no longer required.
  541. We can also display some interesting patterns using the colour demo. For
  542. example:
  543.  
  544.         REM 1.1.4B Colour Demo
  545.         SCREEN 1,320,200,5,1
  546.         WINDOW 2,"ColorDemo",(0,0)-(62,62),16,1
  547.         FOR m = 0 TO 31
  548.            FOR x = -m TO m
  549.               FOR y = -m to m
  550.                 PSET (31+x,31+y),((ABS(x) AND ABS(y))+32-m) MOD 32
  551.               NEXT y
  552.            NEXT x
  553.         NEXT m
  554.         WHILE INKEY$="":WEND
  555.         WINDOW CLOSE 2
  556.         SCREEN CLOSE 1
  557.  
  558. OR:
  559.  
  560.         REM 1.1.4C Pyramid
  561.         SCREEN 1,320,200,5,1
  562.         WINDOW 2,,(0,0)-(20,10),16,1
  563.         FOR y = 0 TO 19
  564.            FOR x = 0 TO 19
  565.               f1 = ABS(x-10)
  566.               f2 = ABS(y-10)
  567.               IF f1<f2 THEN SWAP f1,f2
  568.               PSET(x,y),31-f1
  569.            NEXT x
  570.         NEXT y
  571.         WHILE INKEY$ = "": WEND
  572.         WINDOW CLOSE 2
  573.         SCREEN CLOSE 1
  574.  
  575.  
  576.                                 PAGE 5
  577.  
  578. ----------------------------------------------------------------------------
  579.  
  580. These two programs demonstrate different methods of colour manipulation. In
  581. the first program we joined the X and Y values using AND. You can also
  582. create nice patterns by multiplying the values or by using XOR.
  583.  
  584. In the second program, we drew a square that had a dark outer edge and
  585. became progressively lighter towards the centre. It creates the effect of
  586. looking at a pyramid from the top. To do this, we used only colour
  587. registers 21 thru 31. These registers contain varying levels of grey shades
  588. useful in generating 3-D effects.
  589.  
  590.                         --------------------------------
  591.  
  592. 1.1.5 MORE ABOUT PSET AND PRESET.
  593.  
  594. We mentioned previously that PRESET erases the pixels that PSET set. This
  595. is only true as long as you do not specify a colour value with PRESET:
  596.  
  597.         PSET(100,100)
  598.         PRESET(100,100)
  599.  
  600. The above example demonstrates what we mean. We set a pixel and then erase
  601. it.
  602.  
  603. The example below has a completely different action, the pixel is drawn in
  604. white and not erased:
  605.         
  606.         PSET(100,100),1
  607.         PRESET(100,100),1
  608.  
  609. The moment you specify a colour register both statements will have the same
  610. result. It becomes a matter of personal preference which statement you use.
  611.  
  612. An alternative method to using PRESET(x,y) to erase pixels is to use
  613. PRESET(x,y),0. Why are there two statements which seem to do the same
  614. thing? The default colour ( the colour used if you do not specify a colour
  615. value with PSET and PRESET) is the key difference. With PSET the default
  616. colour is the foreground colour and with PRESET it is the background
  617. colour. This also has an effect on changes to the foreground and background
  618. colours. You do not have to concern yourself with these values when using
  619. PSET  to erase pixels.
  620.  
  621.                                 PAGE 6
  622.  
  623. ----------------------------------------------------------------------------
  624.  
  625. Using both statements in a program makes it much easier to understand what
  626. is going on. You can see right away where pixels are being drawn or erased.
  627.  
  628.         REM 1.1.5 Demo for P(RE)SET
  629.         RANDOMIZE TIMER
  630.         SCREEN 1,320,200,5,1
  631.         WINDOW 2,,(0,0)-(311,185),16,1
  632.         l=.8
  633.         DIM y(l*100)
  634.         WHILE INKEY$ = ""
  635.         COLOR INT(RND*32),INT(RND*32)
  636.         CLS
  637.         FOR j = 1 TO 4
  638.            y(j) = 50+RND*80: s(j) = RND*50
  639.         NEXT j
  640.         FOR x = 0 TO 6.2+l STEP .04
  641.            FOR j = 1 TO 4 STEP 2
  642.               PRESET((x-1)*50,y(j)-s(j)*SIN(x-1))
  643.               PRESET((x-1)*50,y(j+1)-s(j+1)*COS((x-1)*j))
  644.               PSET(x*50,y(j)-s(j)*SIN(x)),INT(RND*32)
  645.               PSET(x*50,y(j+1)-s(j+1)*COS(x*j))
  646.            NEXT j
  647.         NEXT x
  648.         WEND
  649.         WINDOW CLOSE 2
  650.         WINDOW CLOSE 1
  651.  
  652. In this program, lines of different lengths move across the screen. As in
  653. the first PRESET demo program, we set a pixel at the front of a line and
  654. erase one at the end. What is special about this program is the changing of
  655. the foreground and background colours. As you can see, erasing using PRESET
  656. is quite easy.
  657.  
  658.                         -----------------------------
  659.  
  660. 1.1.6 THE "OPPOSITE" OF PSET: THE POINT STATEMENT.
  661.  
  662. By opposite we mean instead of setting a pixel we can read a pixel to see
  663. if it is set and what colour it is. To do this we use the POINT statement:
  664.  
  665.         PRINT POINT(x,y)
  666.  
  667. The result will either be the colour or a value indicating that the pixel
  668. (x,y) coordinates are not in the output window. In the first case, the
  669. number of colour register is printed, in the second a value of -1 is
  670. returned.
  671.  
  672.                                 PAGE 7
  673.  
  674. ----------------------------------------------------------------------------
  675.  
  676. Our next program creates a few graphic lines, then the POINT statement is
  677. used to determine if a pixel has been set. The resulting picture will look
  678. as if it was created by using randomly set pixels.
  679.  
  680.         REM 1.1.6 Patterns
  681.         SCREEN 1,320,200,5,1
  682.         WINDOW 2,,(0-0)-(80,80),16,1
  683.         RANDOMIZE TIMER
  684.         x=40
  685.         y=40
  686.         Direction:
  687.         dx = INT(RND*5)-2
  688.         dy = INT(RND*5)-2
  689.         IF dx = 0 AND dy = 0 THEN Direction
  690.         IF ABS(dx) > ABS(dy) THEN
  691.             st = ABS(dx)
  692.         ELSE    
  693.             st = ABS(dy)
  694.         END IF
  695.         WHILE INKEY$ = ""
  696.           IF POINT (x+dx, y+dy)=-1 THEN Direction
  697.           FOR i = 1 TO st
  698.              x = x+dx/st
  699.              y = y+dy/st
  700.                 PSET (x,y),POINT(x,y) MOD 31+1
  701.           NEXT i
  702.         WEND
  703.         WINDOW CLOSE 2
  704.         SCREEN CLOSE 1
  705.  
  706. The arrangement used to build this screen is quite simple. One pixel
  707. wanders around the screen. (With each move we check the pixels positions
  708. colour register and increment it by one.) When the moving pixel hits a
  709. window border we change directions.
  710.  
  711. End the program by pressing any key.
  712.  
  713.                 ---------------------------------------------
  714.  
  715. 1.1.7 RELATIVE ADDRESSING.
  716.  
  717. With PSET, and almost all other graphics statements in AmigaBASIC, there
  718. are two modes of addressing. We can easily compare the firt method to home
  719. addresses and postcodes. When you send a letter it always arrives at the
  720. address to which you send it (BULLSHIT!!!!). This is the method of
  721. addressing we have been using in our programs:
  722.  
  723.         PSET (20,30)
  724.  
  725.                                 PAGE 8
  726.  
  727. ----------------------------------------------------------------------------
  728.  
  729. The values 20 and 30 are the absolute coordinates of the pixel we want to
  730. set in its row and column. This method of addressing is named "absolute".
  731. The second method of addressing is called "relative". Relative address
  732. coordinates do not refer directly to a row and column position, instead
  733. they point to a position relative to your current position. This is like
  734. telling the computer: from your current position move three pixels to the
  735. right and then two down. The key to this method is the current position of
  736. the graphic cursor. The indicator for relative addressing is the word STEP
  737. which is positioned before the parenthesis:
  738.  
  739.         PSET STEP (3,2)
  740.  
  741. Although we cannot ask where the graphics cursor is, we can move it easily
  742. without doing any drawing:
  743.  
  744.         v = POINT(x,y)
  745.  
  746. We move the graphics cursor automatically when we set or erase points. By
  747. using this form of the POINT statement, we can relocate it anywhere we
  748. want. The variable 'v' can be any variable not already used in your
  749. program.
  750.  
  751. When you start a program the graphic cursor will always be in the centre of
  752. the output window.
  753.  
  754. If you use relative addressing with constant coordinates, you plot pixels
  755. with the same offset between them. This is not something you would
  756. necessarily want, but our next sample program demonstrates how this works.
  757. This program is very similar to our first drawing program but instead of
  758. setting one pixel when you press a mouse button it will set several pixels
  759. giving a brush effect.
  760.  
  761.         REM 1.1.7 Relative Addressing.
  762.         WHILE INKEY$ = ""
  763.         IF MOUSE(0) <>0 THEN
  764.            x = MOUSE(1)
  765.            y = MOUSE(2) 
  766.            PSET (x,y)
  767.            PSET STEP (10,10)
  768.            PSET STEP (10,-10)
  769.            PSET STEP (-10,-10)
  770.            PSET STEP (10,0)
  771.         END IF
  772.         WEND
  773.  
  774. The first pixel we set using an absolute address. The other four pixels we
  775. set with a relative address, which made the distance between them the same.
  776.  
  777.                                 PAGE 9
  778.  
  779. ----------------------------------------------------------------------------
  780.  
  781. 1.2 THE LINE STATEMENT.
  782.  
  783. The LINE statement has two uses that look similar, but produce completely
  784. different results. First, as the name implies, you can draw striaght lines.
  785. You can also use LINE to draw boxes. We will discuss the second form of the
  786. LINE statement in more detail later on.
  787.  
  788.         LINE (20,10)-(200,100),2
  789.  
  790. The above statement draws a black (colour register 2) line from point
  791. (20,10) to point (200,100).
  792.  
  793.                 ------------------------------------------
  794.  
  795. 1.2.1 THE POWER OF LINE.
  796.  
  797. With the PSET statement, you can perform almost anything that is possible
  798. in the computer graphics world. You can create any desired graphics or
  799. lines you want. The problem with using PSET by itself is the time involved.
  800. The time saved using the LINE statement is enormous and easily
  801. demonstrated:
  802.  
  803.         REM 1.2.1 Benchmark for PSET with LINE.
  804.         REM straight line with PSET
  805.         FOR i = 0 TO 80
  806.            PSET(i,i)
  807.         NEXT i
  808.         REM straight line with line
  809.         LINE (180,0)-(0,180)
  810.  
  811. The LINE statement opens up more possibilities, probably a lot more than
  812. the PSET statement. In the same way you form lines by setting pixels one
  813. after another, you can draw a line simply by specifying the start and end.
  814. In this example, the start and end coordinates for the LINE statement were
  815. in the same row.
  816.  
  817.                 ----------------------------------------------
  818.  
  819. 1.2.2 THE MOIRE EFFECT.
  820.  
  821. Moire patterns become visible whenever you draw lines close to or
  822. intersecting each other. Using this effect you can design astounding
  823. pictures. Watch the graphics created by the program below.
  824.  
  825.                                 PAGE 10
  826.  
  827. ----------------------------------------------------------------------------
  828.  
  829.         REM moire-Lattice.
  830.         a=182   'size of rectangle '
  831.         FOR s = 1 TO 10
  832.            CLS
  833.            FOR i = 0 TO a STEP s
  834.               LINE (140,1)-(140+2*a,i),2
  835.               LINE (140,1)-(140+2*i,a),2
  836.               LINE (140+2*a,a)-(140,i),2
  837.               LINE (140+2*a,a)-(140+2*i,1),2
  838.            NEXT i
  839.            WHILE INKEY$="": WEND
  840.         NEXT s
  841.  
  842. We draw lines from two corners of the rectangle to the opposite side. The
  843. Moire effect shows up at the connecting points of both corners because that
  844. is where we have drawn most of the lines.
  845.  
  846. We can also achieve this effect by drawing many lines from a single point
  847. and increase the effect by alternating between two different colors.
  848.  
  849.         REM 1.2.2B Moire Demo 2.
  850.         xmax = 618 ' size of output window     
  851.         ymax = 186
  852.         COLOR 1,2       'background black
  853.         Start:
  854.         CLS     
  855.         xm = INT(RND*xmax)      'Coordinates of Centre Point
  856.         ym = INT(RND*ymax)
  857.         FOR i = 0 TO ymax
  858.            LINE (xm,ym)-(0,i),i MOD 2+1
  859.            LINE (xm,ym)-(xmax,i),i MOD 2+1
  860.         NEXT i
  861.         FOR i = 0 TO xmax
  862.            LINE (xm,ym)-(i,0),i MOD 2+1
  863.            LINE (xm,ym)-(i,ymax),i MOD 2+1
  864.         NEXT i
  865.         WHILE INKEY$ = "": WEND
  866.         GOTO Start
  867.  
  868. When you observe the graphics created by this program, it is hard to
  869. believe we created them so easily.
  870.  
  871.                 ------------------------------------------
  872.  
  873. 1.2.3 QUIX, LINE GALORE.
  874.  
  875. Again, we come back to the speed of the line statement. In the following
  876. program, we let quix race around the screen. Quix is composed of many lines
  877. that are more or less parallel. The movement of quix is caused by erasing
  878. lines at one end and drawing them at the opposite end. It becomes difficult
  879. to tell where a line starts or ends,since the portion added uses the same
  880. end coordinates as the line it is being added to. We simply modify the
  881. coordinates slightly to make the existing line longer.
  882.  
  883.  
  884.                                 PAGE 11
  885.  
  886. ----------------------------------------------------------------------------
  887.  
  888.         REM 1.2.3 Quix.
  889.         DEFINT a-z
  890.         SCREEN 1,320,200,5,1
  891.         WINDOW 2,"QUIX",(0,0)-(297,185),31,1
  892.         RANDOMIZE TIMER 
  893.         a=20
  894.         DIM x(1,a),y(1,a)
  895.         x(0,0)=150
  896.         y(0,0)=150
  897.         x(1,0)=170
  898.         y(1,0)=100
  899.         WHILE INKEY$ = ""
  900.            FOR z = 0 TO a
  901.               LINE (x(0,z),y(0,z))-(x(1,z),y(1,z)),0
  902.               FOR i = 0 TO 1
  903.         newx:   x(i,z)=ABS(x(i,alt)+RND*20-10)
  904.                 IF x(i,z)>WINDOW(2) THEN newx
  905.         newy:   y(i,z)=ABS(y(i,alt)+RND*20-10)
  906.                 IF y(i,z)>WINDOW(3) THEN newy
  907.               NEXT i
  908.               f1 = f1 MOD 31 + 1
  909.               LINE (x(0,z),y(0,z))-(x(1,z),y(1,z)),f1
  910.               alt = z
  911.            NEXT z
  912.         WEND
  913.         WINDOW CLOSE 2
  914.         SCREEN CLOSE 1
  915.  
  916. While quix is moving around you can stop it by clicking and holding on the
  917. window size gadget and shrinking the window. The coordinates used by quix
  918. will never be greater than the current window size. You can determine the
  919. actual size of the output window by using WINDOW(2) (width) and WINDOW(3)
  920. heigth.
  921.  
  922.                 ---------------------------------------------
  923.  
  924. 1.2.4 FUNCTION PLOTTER.
  925.  
  926. A function plotter is one of many practical mathematical applications
  927. requiring graphics. It can be a great help in the visual examination of
  928. functions. Experimenting with parameters and functions can also be a lot of
  929. fun while looking for interesting curves. THe function plotter is very
  930. comprehensive and user friendly. For example, the program will compute your
  931. coordinates so that the function plotted will always be within the window
  932. limits. 
  933.  
  934.                                 PAGE 12
  935.  
  936. ----------------------------------------------------------------------------
  937.  
  938.         REM 1.2.4 FUNCTION PLOTTER.
  939.         DEFDBL x,y,m,f
  940.         DIM y(618)      ' Maximum number of function values.
  941.         x1 = -10: x2=10 ' value limits.
  942.         func = 1        ' First function.
  943.         coordinates=1   ' Coordinates intersect at.
  944.         MENU 1,0,1,"Activity          "
  945.         MENU 1,1,1,"Draw Function     "             
  946.         MENU 1,2,1,"Enter coordinates "
  947.         MENU 1,3,1,"Crosshairs off    "
  948.         MENU 1,4,1,"Quit              "
  949.         MENU ON
  950.         MENU 2,0,1,"Function          "
  951.         DEF FNy1(x) = SIN(x)/(x^2+1)
  952.         a$(1)="y=sin(x)/(x^2+1) "
  953.         MENU 2,1,1,a$(1)
  954.         DEF FNy2(x) = SIN(x)*10-1/x+x^2
  955.         a$(2)="y=sin(x)*10-1/x+x^2"
  956.         MENU 2,2,1,a$(2)
  957.         DEF FNy3(x) = SIN(1/x)/x
  958.         a$(3)="y=sin(1/x)/x     "
  959.         MENU 2,3,1,a$(3)
  960.         DEF FNy4(x)=(EXP(x)-1)/(EXP(x)+1)
  961.         a$(4)="y=(e^x-1)/(c^x+1)        "
  962.         MENU 2,4,1,a$(4)
  963.         WINDOW 1, a$(1),,23
  964.         GOSUB Calculate
  965.         Select:      SLEEP
  966.                      ON MENU GOSUB Branch
  967.                      GOTO Select
  968.         Selection:   ON MENU(1) GOSUB Calculate, Entry, Crosshair, Quit
  969.                      RETURN
  970.         Branch:      ON MENU(0) GOTO Selection
  971.                      func = MENU(1)
  972.                      WINDOW 1,a$(func)
  973.         Entry:       WINDOW 2,"Coordinate Entry",(0,0)-(250,9),16
  974.                      INPUT "Start Value : ";x1
  975.                      INPUT "End Value   : ";x2
  976.                      IF x2<x1 THEN SWAP x1,x2
  977.                      WINDOW CLOSE 2
  978.         Calculate:   IF x1=x2 THEN Entry
  979.                      fwidth = WINDOW(2)
  980.                      WINDOW 2,"Calculating function - wait",(0,0)-(300,0),0
  981.                      min = 0
  982.                      max = 0
  983.                      ON ERROR GOTO Errorcond
  984.                      FOR i = 0 TO fwidth
  985.                         fvalue = x1+(x2-x1)*i/fwidth
  986.                         ON func GOSOB F1,F2,F3,F4
  987.  
  988.  
  989.                                 PAGE 13
  990.  
  991. ----------------------------------------------------------------------------
  992.  
  993.                         IF y(min)>y(i) THEN min = i
  994.                         IF y(max)<y(i) OR y(max) = 9999 THEN max = i
  995.         Proceed:     NEXT i
  996.                      ON ERROR GOTO 0
  997.                      min=y(min)
  998.                      max=y(max)
  999.                      WINDOW CLOSE 2
  1000.                      GOSUB Title
  1001.         Drawplot:    CLS
  1002.                      fheight = WINDOW(3)-8
  1003.                      IF coordinates=1 THEN
  1004.                       IF min<=0 AND max >=0 THEN
  1005.                         h=fheight+min*fheight/(max-min)         
  1006.                         LINE(0,h)-(fwidth,h),2
  1007.                       END IF
  1008.                       IF x1<0 and x2>0 THEN
  1009.                         b=-x1*fwidth/(x2-x1)
  1010.                         LINE(b,0)-(b,fheight),2
  1011.                       END IF
  1012.                      END IF
  1013.                      IF min=max THEN 'When min=max then draw striaght line
  1014.                        IF max=9999 THEN ' Funtion value not defined
  1015.                           CLS
  1016.                        ELSE
  1017.                           LINE(0,fheight/2)-(fwidth,fheight/2)
  1018.                        END IF
  1019.                      END IF
  1020.                      j=0
  1021.                      WHILE (y(j)=9999 AND j<618) ' find first defined
  1022.                                                    function value'
  1023.                        j=j+1
  1024.                      WEND
  1025.                      IF j=618 THEN RETURN
  1026.                      PSET (j,fheight-(y(j)-min)*fheight/(max-min)
  1027.                      FOR i=j+1 TO fwidth
  1028.                        IF y(i)<>9999 THEN
  1029.                          IF flag THEN
  1030.                             PSET(i,fheight-(y(i)-min)*fheight/(max-min))
  1031.                             flag=0
  1032.                          ELSE
  1033.                             LINE (i,fheight-(y(i)-min)*fheight/(max-min))
  1034.                          END IF
  1035.                        ELSE
  1036.                          flag = 1
  1037.                        END IF
  1038.                      NEXT i
  1039.                      RETURN
  1040.         Errorcond:   y(i) = 9999
  1041.                      RESUME Proceed
  1042.         F1:          y(i) = FNy1(fvalue)
  1043.                      RETURN
  1044.  
  1045.                                 PAGE 14
  1046.  
  1047. ----------------------------------------------------------------------------
  1048.  
  1049.         F2:          y(i) = FNy2(fvalue)
  1050.                      RETURN
  1051.         F3:          y(i) = FNy3(fvalue)
  1052.                      RETURN
  1053.         F4:          y(i) = FNy4(fvalue)
  1054.                      RETURN
  1055.         Title:       MENU 3,0,1,MID$(STR$(x1),1,5)+
  1056.                      "<x<"+MID$(STR$(x2),1,5)
  1057.                      MENU 4,0,1,MID$(STR$(min),1,5)+
  1058.                      "<y<"+MID$(STR$(max),1,5)
  1059.                      RETURN
  1060.         Crosshair:   IF coordinates = 1 THEN
  1061.                         coordinates = 0
  1062.                         MENU 1,3,1,"Crosshairs ON       "
  1063.                      ELSE
  1064.                         coordinates = 1
  1065.                         MENU 1,3,1,"Crosshairs OFF      "
  1066.                      END IF
  1067.                      GOTO Drawplot
  1068.         Quit:        WINDOW 1,"Function Plotter",(0,0)-(617,184),31
  1069.                      MENU RESET
  1070.                      END
  1071.  
  1072. You are probably asking yourself what does a function plotter have to do
  1073. with the LINE statement since we form a function by plotting points. Our
  1074. program works by plotting a point for each curve. Between these points are
  1075. large gaps and if we only plotted the calculated points our function would
  1076. not look like a curve. We make the connection between all of these points
  1077. by using the LINE statement.
  1078.  
  1079.                 ------------------------------------------
  1080.  
  1081. 1.2.4.1 FUNCTION PLOTTER MODES AND MENU CONTROLS.
  1082.  
  1083. This program has two standard and two pseudo menus. The pseudo menus have
  1084. no sub-menus and only provide you with information. The first pseudo menu
  1085. displays the limit values of the curve in the X direction. The second
  1086. pseudo menu lists the maximum and minimum Y values of the function. Both of
  1087. these menus are only visible after your funcion has been plotted and
  1088. changed with each function.
  1089.  
  1090. The activity menu has four sub-menus. Sub menus one redraws the current
  1091. function and is used after you have changed the size of the output window.
  1092. The other three menus are for entering new coordinates, making the
  1093. crosshair visible and invisible and exiting the program. With the second
  1094. menu you can choose from one of four PRESET mathematical functions.
  1095. Unfortunately with BASIC it is not possible for you to input the function
  1096. formulas. If you want to test other functions, you can do so by changing
  1097. those at the beginning of the program. You will also have to change the
  1098. text for the a$(n) since it lists the function for menu 2.
  1099.  
  1100.                                 PAGE 15
  1101.  
  1102. ----------------------------------------------------------------------------
  1103.  
  1104. 1.2.4.2 UNDEFINED FUNCTION VALUES.
  1105.  
  1106. This program allows you to view mathematical functionson your screen
  1107. without spending a lot of time figuring out values. For example, lets say
  1108. you want to compute the value of a curve 1/x and you input a value of x =
  1109. 0. Since division by zero creates an error and we used the ON-ERROR-GOTO
  1110. assignment before calculating the function values, BASIC branches on the
  1111. error. Simply put, instead of the program halting on the error it goes to a
  1112. specified error handler routine which processes the problem.
  1113.  
  1114. In this program, the function value on specific errors will default to
  1115. 9999. If the drawing routine receives this value, it then knows the pixel
  1116. should not be plotted.
  1117.  
  1118. In addition to division by zero, overflow errors are also handled. There
  1119. is, of course, the danger of other unforseen errors happening at which time
  1120. the program will stop.
  1121.  
  1122. For the program to properly interpret errors that occur after the function
  1123. calculations, the ON-ERROR-GOTO assignment is switched off again.
  1124.  
  1125.                 --------------------------------------------
  1126.  
  1127. 1.2.4.3 SCALING.
  1128.  
  1129. You can directly affect the size and shape of a curve by enlarging or
  1130. shrinking it. When you change the size of the output window there is a
  1131. proportional effect on the displayed curve by either stretching or
  1132. compressing it.
  1133.  
  1134. By scaling we mean that a curve is always displayed to fill the entire
  1135. window. However, the values of the X and Y axis are dependent on the height
  1136. and width of the window. Stertching a curve can sometimes produce confusing
  1137. results. On the other hand, compressing it can cause a smooth straight
  1138. curve to appear more sloped.
  1139.  
  1140. The advantage to this method of presentation is that you do not have to
  1141. worry much about the course of the curves. As mentioned previously, you can
  1142. obtain more information about a curve from the menus.
  1143.  
  1144.                                 PAGE 16
  1145.  
  1146. ----------------------------------------------------------------------------
  1147.  
  1148. 1.2.5 DRAWING RECTANGLES.
  1149.  
  1150. Earlier we discussed the LINE statement not only to draw lines, but also
  1151. rectangles. Now we will show you how to draw a rectangle with a single LINE
  1152. statement. The difference between lines and rectangles is a B, at the end
  1153. of the statement.
  1154.  
  1155.         LINE (20,10)-(200,100),2,B
  1156.  
  1157. This statement draws an unfilled black rectangle on the screen. The first
  1158. coordinate opair is the upper left hand corner and the second pair is the
  1159. lower right hand corner. You can see it is very easy to draw rectangles.
  1160. Althought the sides will always be parallel to the output window, this type
  1161. of rectangle is very useful.
  1162.  
  1163. You can also draw filled rectangles instead if unfilled by using ,BF
  1164. instead of ,B at the end of the statement.
  1165.  
  1166.         LINE (30,10)-(300,100),2,BF
  1167.  
  1168. If you leave out the color parameter the rectangle is drawn in the
  1169. foreground colour.
  1170.  
  1171. With this statement we can also perform a speed test. Our test program is
  1172. similar to the boxes demo of the workbench. We will draw filled rectangles
  1173. with random coordinates and colours.
  1174.  
  1175.         REM 1.2.5 Speed test of
  1176.         REM     the LINE statement
  1177.         WHILE INKEY$ = ""
  1178.            x = WINDOW(2)
  1179.            Y = WINDOW(3)
  1180.            LINE (RND*x,RND*y)-(RND*x,RND*y),INT(RND*4),BF
  1181.         WEND
  1182.  
  1183. Even though this is a very simple program, it seems amazing if you are not
  1184. familiar with the Amiga. The speed with which the Amiga draws and fills
  1185. rectangles is very fast, so fast in fact that you do not have time to count
  1186. them. Keep in mind that these are not all small rectangles. Some of them
  1187. have thoiusands of pixels and you still cannot see the difference.
  1188.  
  1189.                                 PAGE 17
  1190.  
  1191. ----------------------------------------------------------------------------
  1192.  
  1193. 1.2.6 RELATIVE ADDRESSING WITH THE LINE STATEMENT.
  1194.  
  1195. You can use relative co-ordinates with the LINE statement in either mode in
  1196. exactly the same way as you used them with PSET.
  1197.  
  1198. The first coordinate pair is relative to the graphic cursor position and
  1199. the second pair is relative to the starting point of the line.
  1200.  
  1201. Both coordinates do not have to be relative. The following statement draws
  1202. a line from (30,20) to (20,120)
  1203.  
  1204.         LINE (30,20)- STEP(-10,100)
  1205.  
  1206. If you want to continue drawing from the current position of the graphic
  1207. cursor, you just leave the first coordinate pair out. We will demostrate
  1208. this method in the following program in which we will draw multiple
  1209. rectangles inside of each other:
  1210.  
  1211.         REM 1.2.6A Boxes within Boxes.
  1212.         SCREEN 1,320,200,2,1
  1213.         WINDOW 2,"Rotated Rectangle",(0,0)-(311,185),16,1
  1214.         COLOR 2,1
  1215.         CLS
  1216.         d=5     'Distance (1-10)
  1217.         b=60    'Width of first box.    
  1218.         FOR x = 0 TO 311 STEP b
  1219.           FOR y = 0 TO 185 STEP b
  1220.               x1=x: x2=x+b
  1221.               y1=y: y2=y
  1222.               FOR a = 0 TO .7 STEP ATN(d/b) 'a<pi/4
  1223.                 IF((x+y)/b)MOD 2 = 0 THEN       'rotate direction
  1224.                   LINE (x1,y1)-(x2,y2)
  1225.                   LINE -(2*x+b-x1,2*y+b-y1)
  1226.                   LINE -(2*x+b-x2,2*y+b-y2)
  1227.                   LINE -(x1,y1)
  1228.                 ELSE
  1229.                   LINE (2*x+b-x1,y1)-(2*x+b-x2,y2)
  1230.                   LINE -(x1,2*y+b-y1)
  1231.                   LINE -(x2,2*y+b-y2)
  1232.                   LINE -(2*x+b-x1,y1)
  1233.                 END IF
  1234.                 x1=x1+COS(a)*d  'calculate next rectangle
  1235.                 x2=x2-SIN(a)*d
  1236.                 y1=y1+SIN(a)*d
  1237.                 y2=y2+COS(a)*d
  1238.               NEXT a
  1239.           NEXT y
  1240.         NEXT x
  1241.         WHILE INKEY$="": WEND
  1242.         WINDOW CLOSE 2
  1243.         SCREEN CLOSE 1
  1244.  
  1245.                                 PAGE 18
  1246.  
  1247. ----------------------------------------------------------------------------
  1248.  
  1249. When the program is finished you can hardly distinguish the individual
  1250. rectangles. They have dissappeared in the overall pattern. This effect is
  1251. increased by neighboring rectangles being rotated in the opposite
  1252. direction.
  1253.  
  1254. Both coordinates pairs are required for only the first line of a rectangle
  1255. or another geomertric figure.
  1256.  
  1257. The second coordinate pair of the LINE statement determines where the
  1258. graphic cursor will be after drawing the line. If you plan ahead you can
  1259. save yourself some work: Using LINE to draw boxes, you can swap the X and Y
  1260. coordinates and determine what corner the graphic cursor will be after the
  1261. statement. This is very useful when using relative addressing.
  1262.  
  1263. The following program draws a random bar graph of the type popular for
  1264. statistics. Our bar graph is to be three dimensional so we have created a
  1265. shadow composed of line.
  1266.  
  1267.         REM 1.2.6B Bar Graph
  1268.         RANDOMIZE TIMER
  1269.         SCREEN 1,320,200,4,1
  1270.         WINDOW 2,"Bargraph",,31,1
  1271.         FOR i = 0 TO 7
  1272.             x = 30+i*37
  1273.             y = INT(RND*160)+1
  1274.             LINE (x,180-y)-STEP(6,-6),i+1
  1275.             LINE -STEP (0,y),i+1
  1276.             LINE -STEP (-6,6),i+1
  1277.             LINE -STEP (-20,-y),i+1,BF
  1278.             LINE -STEP (6,-6),i+1
  1279.             LINE -STEP (20,0),i+1
  1280.         NEXT i
  1281.         WHILE INKEY$="": WEND
  1282.         WINDOW CLOSE 2
  1283.         SCREEN CLOSE 1
  1284.  
  1285. Except for the first coordinate pair of each bar all coordinates are
  1286. relative, including those of the boxes. Using this method can save you some
  1287. time because you have to calculate only a few coordinates.
  1288.  
  1289.                                 PAGE 19
  1290.  
  1291. -----------------------------------------------------------------------------
  1292.                
  1293. 1.3 THE CIRCLE STATEMENT.
  1294.  
  1295. For a computer that is designed to handle professional graphics we would
  1296. expect BASIC to include a 'circle' statement.
  1297.  
  1298. In school you learned that you require a center and a radius to draw a 
  1299. circle. This is the same for AmigaBASIC.
  1300.  
  1301.     CIRCLE (200,100),100
  1302.  
  1303. We can draw coloured circles in the same way. The value for the colour 
  1304. register is simply added at the end of the statement:
  1305.  
  1306.     CIRCLE (200,100),100,2
  1307.  
  1308. With both circles there are two notable points:
  1309.  
  1310. 1.) Both figures are more ellipse shaped than round.
  1311.  
  1312. 2.) The radius is smaller than the height in pixels of the window, but with 
  1313.     a radius of 100 the circle should not fit in the window.
  1314.  
  1315. Both points are dependant upon each other and upon the aspect ratio.
  1316.  
  1317.         -----------------------------------------
  1318.  
  1319. 1.3.1 THE ASPECT RATIO.
  1320.  
  1321. You have probably experimented with the adjustments on the back of your
  1322. monitor. One of these adjustments changes the vertical height of your screen.
  1323. Using this adjustment you could expand your screen vertically until our
  1324. last circle appeared round. The problem with doing this is that you would cut
  1325. off the top and bottom of the screen. If you changed to a different screen
  1326. resolution you circle would be egg-shaped.
  1327.  
  1328. We have a much better solution. You can use a parameter with the CIRCLE 
  1329. statement the adjusts the pixel height and width ratios to round the image.
  1330. This is how you do it:
  1331.  
  1332.     CIRCLE (100,100),100,,,,2
  1333.  
  1334. There are four commas between the radius and the aspect ratio because we 
  1335. have left ut 3 parameters: the colour, which we already selected and two
  1336. angle parameters that we will discuss later.
  1337.  
  1338.                 PAGE 20
  1339.  
  1340. ----------------------------------------------------------------------------
  1341.  
  1342. Drawing perfect circles is not the only way that you can use the aspect 
  1343. ratio. In our next program, which draws many ellipses and circles, you
  1344. can create your own shapes. The shapes we achieve with this program range 
  1345. from circles to diamonds to four pointed stars. All of these figures are 
  1346. created using many arcs:
  1347.  
  1348.     REM 1.2.1 Ellipses
  1349.     SCREEN 1,320,200,2,1    
  1350.     WINDOW 2,,(0,0)-(311,185),16,1
  1351.     FOR g = 0 TO 80 STEP 5
  1352.         CLS
  1353.         FOR f = .0001 TO 1 STEP .1
  1354.         CIRCLE(100,100),(80-g*f),,,,f
  1355.         CIRCLE(100,100),(80-g*f),,,,1/f
  1356.         NEXT f
  1357.         WHILE INKEY$ = "": WEND
  1358.     NEXT g
  1359.     WINDOW CLOSE 2
  1360.     SCREEN CLOSE 1
  1361.  
  1362. We have used the lower resolution of 320*200 for this program because the 
  1363. aspect ratio is equal to one. This is the reason the horizontal and 
  1364. vertical allipses are so similar. The difference is that once we use an 
  1365. aspect ratio of F which is smaller than 1 and the second time we use 1/F 
  1366. which is larger than one. Thus the ellipses are basically the same, except 
  1367. one is tall and the other is wide.
  1368.  
  1369. All of the figures are dependant on the values of the aspect ratio and the 
  1370. radius. The larger we make the value of F, the rounder the circle and, at the
  1371. same time, the smaller the radius. How small the radiius becomes is
  1372. different for each figure.
  1373.  
  1374.         ------------------------------------------------
  1375.  
  1376. 1.3.1.1 ANIMATION USING CIRCLE
  1377.  
  1378. The next program contains simple animated graphics. It simulates a bouncing
  1379. ball on the screen. With each bounce the ball will compress slightly as if 
  1380. made of rubber. This action gives it the next bounce.
  1381.  
  1382.     REM 1.3.1.1A Springing Ball.
  1383.     SCREEN 1,320,200,2,1
  1384.     WINDOW 2,,(0,0)-(100,100),16,1
  1385.     WHILE INKEY$=""
  1386.         FOR i = 0 TO 3.14 STEP .08
  1387.         f=1
  1388.         y=70*SIN(i)
  1389.         IF y<10 THEN f=.5+y/20
  1390.         CLS
  1391.         CIRCLE (50,100-y),20,1,,,f
  1392.         NEXT
  1393.     WEND
  1394.     WINDOW CLOSE 2
  1395.     SCREEN CLOSE 1
  1396.  
  1397.                 PAGE 21
  1398.  
  1399. ----------------------------------------------------------------------------
  1400.  
  1401. The aspect ratio is dependant on the height of the ball which we calculate
  1402. with the sine function. When the ball is lower than the radius of the 
  1403. circle, we change the value of f (aspect ratio) and the ball compresses.
  1404.  
  1405. The principle of our animation is simple: We draw a circle and calculate 
  1406. the position of the next circle. Before we draw the next circle we clear the
  1407. screen. Because you dont have to calculate the circle, it is simpler and 
  1408. faster to clear the screen instead of erasing the existing circle with 
  1409. the background colour. When we use CLS, the blitter, a special graphic
  1410. co-processor, takes care of most of the work. Clearing the screen is a
  1411. small task for the blitter, which can fill areas of up to a millions 
  1412. pixels in a second.
  1413.  
  1414. In the next program, we show you a wire model of a chess piece. When you
  1415. press a key the figure will rotate. You might recognise this figure 
  1416. immediately: its the queen.
  1417.  
  1418. The moire effect, which you saw with the LINE statement, also appears with
  1419. the CIRCLE statement. It will always appear when many lines, or curves in 
  1420. this case, are close together.
  1421.  
  1422.     REM 1.3.1.1.B CHESS PIECE
  1423.     FOR f=0 T0 .5 STEP .05
  1424.         CLS
  1425.         READ l
  1426.         FOR i = 1 TO l
  1427.             READ a
  1428.             CIRCLE (320,150-i*3*2*(.f-5)),a*2,2,,,f
  1429.         NEXT i
  1430.         RESTORE
  1431.         WHILE INKEY$="": WEND
  1432.     NEXT f
  1433.     REM Queen
  1434.     DATA 39,31,29,29,31,26,23
  1435.     DATA 21,27,22,19,16
  1436.     DATA 14,13,13,12,12,12,11,11,11,11,22
  1437.     DATA 16,16,20,16,16
  1438.     DATA 17,18,19,21,23,26,29
  1439.     DATA 27,25,10,10,8
  1440.  
  1441. We only use the CIRCLE statement to rotate this figure. In this program 
  1442. the variable F sets the aspect ratio and the height for the centre point 
  1443. of each circle. At first you will see the queen from the side. As you 
  1444. rotate the figure to a top (or bottom) view, the circles will get rounder
  1445. and the centre points closer together.
  1446.  
  1447.                 PAGE 22
  1448.  
  1449. ----------------------------------------------------------------------------
  1450.  
  1451. 1.3.1.2 THE ASPECT RATIO IN CIRCLE FORMULAS.
  1452.  
  1453. The defualt aspect ratio is 0.44 at a screen resolution of 640*200. 
  1454. Depending on the adjustment of your monitor, the value will draw circles
  1455. or ellipses. The best way to use the CIRCLE statement is with a variable 
  1456. for the aspect ratio that you set at the start of your program. You only
  1457. have to chnage the variable once to change the program for different
  1458. monitors.
  1459.  
  1460. You can use any value between 0 and 200 for the aspect ratio. Using zero
  1461. will result in a horizontal line and using 200 will cause a similar action
  1462. only vertically.
  1463.  
  1464. When you set the aspect ratio smaller than one, the hoizontal distance from
  1465. the corner to the side will be equal to the radius. A value greater than one
  1466. makes the horizontal distance smaller than the radius and the vertical 
  1467. distance equal to the radius. An aspect ratio of 1 will make the height and
  1468. width distances equal to the radius. You can calculate what the distance of
  1469. height and width will be for other aspect ratio values. To do this we must
  1470. understand how the CIRCLE statement computes it's path. The following program
  1471. uses everything we have learned so far about CIRCLE. Although a bit slow in
  1472. BASIC this program will help you understand the aspect ratio:
  1473.  
  1474.     REM 1.3.1.2A Simulation of the CIRCLE statement.
  1475.     CIRCLE (130,100),200,2,,,.2
  1476.     CALL circlefunc (130!,100!,100!,1!,.2)
  1477.     END
  1478.  
  1479.     SUB circelfunc(    mx,my,radius,colr,f) STATIC
  1480.     FOR w = 0 TO 2*3.1415296# STEP .01
  1481.        IF f<1 then
  1482.         x = COS(w)*radius
  1483.          Y = f * SIN(w) * radius
  1484.        ELSE
  1485.         x = COS(w)* radius/f
  1486.         Y = SIN(w)* radius
  1487.        END IF
  1488.        PSET (mx+x,my+y),colr
  1489.     NEXT w
  1490.     END SUB
  1491.  
  1492. The above program shows you where to use the aspect ratio in a formula. It
  1493. is the factor that you multiply with X (for f smaller than one) and divide
  1494. with Y (for f greater than one). Knowing this we can calculate exactly what
  1495. distance a specific pixel will be from the centre. The following program 
  1496. does this job for us by drawing radiuses.
  1497.  
  1498.                 PAGE 23
  1499.  
  1500. ----------------------------------------------------------------------------
  1501.  
  1502.     REM 1.3.1.2B Draw Radiuses.
  1503.     CIRCLE (200,100),100,2,,,.2
  1504.     x1 = 200
  1505.     y1 = 100
  1506.     FOR angle = 0 TO 6 STEP .5
  1507.         x=x1
  1508.         y=y1
  1509.         CALL coordinates (x,y,100!,angle,.2)
  1510.         LINE (x1,y1) - (x,y)
  1511.     NEXT angle
  1512.     END
  1513.  
  1514.     SUB coordinates(mx,my,radius,w,f) STATIC
  1515.     IF f<1 THEN
  1516.         mx=mx+COS(w)*radius
  1517.         my=my-f*SIN(w)*radius
  1518.     ELSE
  1519.         mx=mx+COS(w)*radius/f
  1520.         my=my-SIN(w)*radius
  1521.     END IF 
  1522.         END SUB
  1523.  
  1524. The subroutine calculates intersections and returns the results to the main
  1525. program. You can use the same sub-routine for all of the circles because
  1526. we pass all required parameters to it. The parameter that determines what 
  1527. point you reach is the angle.In the above program we calculate 12 angles 
  1528. between zero and six that set the circumferences for the circles. The sub 
  1529. program then calculates the new values for the variables based on the 
  1530. circle's centre point.
  1531.  
  1532.         ------------------------------------------
  1533.  
  1534. 1.3.2 ANGLE PARAMETERS WITH CIRCLE.
  1535.  
  1536. The angle parameters are the last two parameters for the CIRCLE statement.
  1537. These parameters allow you to draw only a piece of a circle. The first angle
  1538. parameter sets the starting point of an arc and the secnd angle sets the end
  1539. point. Arcs are plotted counter clockwise. The CIRCLE statement looks like
  1540. this with all of the parameters:
  1541.  
  1542.     CIRCLE(mx,my),radius,colour,start,end,aspect
  1543.  
  1544. If you used two CIRCLE statements with the same start and ends but swapped 
  1545. you would draw a complete circle.
  1546.  
  1547. You can specify any start and end angles between -2*PI and 2*PI. You may
  1548. also know from your maths class that in curves 2*PI equals a full circle.
  1549. Here you might get the idea that using both maximum parameters (-2*PI and
  1550. 2*PI) would draw two full circles. That is amthematically logical but false
  1551. in this case. The negative sign in this instance has no mathematical meaning
  1552. but rather a technical one.
  1553.  
  1554.                 PAGE 24
  1555.  
  1556. -----------------------------------------------------------------------------
  1557.  
  1558. If a start angle has a minus sign in front, a line is drawn connecting the
  1559. circle's centre to the curves starting point. This also applies to the
  1560. end angle value. The negative sign means smaller than zero. Even if you use
  1561. a minus sign in front of a zero, it is not negative. To start a curve with
  1562. an angle of zero and draw a line, you must use a value of -0.0001. This 
  1563. value does not have much effect on the angle, but does tell the computer what
  1564. you want to do.
  1565.  
  1566.         ------------------------------------------------
  1567.  
  1568. 1.3.3 RELATIVE ADDRESSING WITH CIRCLE.
  1569.  
  1570. We can also use relative addressing with the CIRCLE statement. When you draw 
  1571. circles using relative addressing, the graphic cursor represents the centre
  1572. point. Unlike PSET and LINE, the graphic cursor does not move to the last 
  1573. pixel drawn, but remains at the centre of the circle.
  1574.  
  1575.         ---------------------------------------------------
  1576.  
  1577. 1.3.4 PIE CHARTS.
  1578.  
  1579. You have probably seen pie charts. For example, we could represent election 
  1580. results using a pie chart to show who won how many seats. The pie sections
  1581. symbolize the total possible seats. The seats of one party are represented 
  1582. by pieces of the pie in the party's colour. An election is only one of many
  1583. uses of the pie chart.
  1584.  
  1585. The Amiga can also display pie charts. Our program displays them almost the 
  1586. same as those you have seen on television, in colour and three dimensional.
  1587.  
  1588.     REM 1.3.4 Pie Charts
  1589.     SCREEN 1,320,200,5,1
  1590.     WINDOW 2,"Pie Charts",,,1
  1591.     f= .3
  1592.     pi=3.141529
  1593.     start:
  1594.     CLS
  1595.     sum=0
  1596.     INPUT "How many values";n
  1597.  
  1598.     IF n<2 THEN
  1599.         CLS
  1600.         PRINT "Demo Program"
  1601.         n = INT(RND(1)*10)+3
  1602.         DIM value(n),  colr(N)
  1603.  
  1604.                 PAGE 25
  1605.  
  1606. ----------------------------------------------------------------------------
  1607.  
  1608.              FOR i = 1 TO 10
  1609.         value(i)=RND(l)*20+1
  1610.             colr(i)=INT(RND(1)*31)
  1611.             sum=sum+value(i)
  1612.          NEXT i    
  1613.     ELSE
  1614.         DIM value(n),colr(n)
  1615.         FOR i = 1 TO n
  1616.         value(i) = 1
  1617.             PRINT i". Value";
  1618.             INPUT value(i)
  1619.           INPUT "Color";colr(i)
  1620.            colr(i)=colr(i) MOD 32
  1621.             sum = sum + value(i)
  1622.         NEXT i
  1623.         CLS
  1624.     END IF
  1625.     REM draw pie chart.
  1626.     mx=WINDOW(2)/2
  1627.     my=WINDOW(3)/2
  1628.     w1=0
  1629.     radius = mx-10
  1630.     CIRCLE(mx,my+20),radius,1,pi,2*pi,f
  1631.     LINE(mx-radius,my)-(mx-radius,my+20)
  1632.     LINE(mx+radius,my)-(mx+radius,my+20)
  1633.     LINE(mx,my)-(mx+radius,my)
  1634.     FOR i = 1 TO n
  1635.         w2=w1+2*pi*value(i)/sum
  1636.         CIRCLE(mx,my),radius,1,-w1,-w2,f
  1637.         REM Color statement.
  1638.         x=COS(w1+(w2-w1)/2)*radius/2
  1639.         y=-f*SIN(w1+(w2-w1)/2)*radius/2
  1640.         PAINT STEP(x,y),colr(i),1
  1641.         IF w2>pi THEN
  1642.         REM Draw Side Line.
  1643.         x=COS(w2)*radius
  1644.         y=-f*SIN(w2)*radius
  1645.         LINE (mx+x,my+y)-(mx+x,my+y+20)
  1646.         REM Colour Side.
  1647.         IF w2-.1>PI THEN
  1648.             x=COS(w2-.1)*radius
  1649.             y=f*SIN(w2-.1)*radius
  1650.            PAINT (mx+x,my+y+18),colr(i),1
  1651.         END IF
  1652.         END IF
  1653.         w1=w2
  1654.     NEXT i
  1655.     INPUT "New Graphic";a$
  1656.     ERASE value,colr
  1657.     IF a$<>"n" THEN start
  1658.     WINDOW CLOSE 2
  1659.     SCREEN CLOSE 1
  1660.  
  1661.                 PAGE 26
  1662.  
  1663. ----------------------------------------------------------------------------
  1664.  
  1665. This program gives you the option of selecting your own values or using 
  1666. randomly generated values. The demo program will start if you enter a zero
  1667. after the value query. If you enter your own values you can select any of 
  1668. 32 colours for eah value.
  1669.  
  1670. Each segment of the pie is drawn separately. Earlier we discussed how you 
  1671. can draw a segment. All you need is a starting and ending angle. You place 
  1672. a minus sign in front of each angle to draw the connecting lines from the 
  1673. centre to the ends of the arc. To bring the colour into each segment we need 
  1674. another statement. All you need is a framed surface and the coordinates of 
  1675. a pixel within this frame to use the PAINT statement. The first requirement
  1676. was fulfilled when we drew the circle segment. To complete the second 
  1677. requirement we have to use the circle formula that we used to demonstrate 
  1678. the aspect ratio. You calculate the centre point of a segment with the
  1679. following:
  1680.  
  1681.     x=COS(w1+(W2-W1)/2)*RADIUS/2
  1682.     Y=-F*SIN(W1+(W2-W1)/2)*RADIUS/2
  1683.  
  1684. In this formula W1 is the start angle, W2 the end angle and F is the aspect
  1685. ratio (here it is always smaller than one). The X and Y variables are not 
  1686. absolute window coordinates, but relative to the circle centre point.
  1687. This allows us to fill the segment with the following statement:
  1688.  
  1689.     PAINT STEP (X,Y),colr(i),1
  1690.  
  1691. The variable colr(i) contains the colour with which we want to fill the 
  1692. segment. The trailing one means we want the segment outlined in white.
  1693.  
  1694. We use a modified version of the formula that calculates centre points to
  1695. separate and colour the borders of the pie.
  1696.  
  1697.         ----------------------------------------------
  1698.  
  1699. 1.3.5 PIXELS AND LINES WITH CIRCLE.
  1700.  
  1701. As silly as it may seem you can also plot pixels, not just ellipses and 
  1702. circles, using the CIRCLE statement. We are not refering to the lines created
  1703. by setting the aspect ratio to zero as you saw above. Nor do we mean the 
  1704. pixel set by using a radius of zero, neither of these actions have a 
  1705. practical use. To draw useful lines and pixels we have to manipulate the 
  1706. angle parameters.
  1707.  
  1708. We set pixels by using the start and end angle values that are equal. You 
  1709. draw a line by making one of the equal signs negative. The distance of a 
  1710. pixel or length of the line are set by the radius and the aspect ratio.
  1711.  
  1712.  
  1713.                 PAGE 27
  1714.  
  1715. ----------------------------------------------------------------------------
  1716.  
  1717. In certain instances, drawing lines with this method is very useful. You
  1718. can draw a line for a specific length and angle from one point. To do this
  1719. with a LINE statement, you would need to know points and would have to
  1720. calculate the angle.
  1721.  
  1722. We can demonstrate the advantages of this unusual use of circle with the
  1723. following program. This is an analog clock that we can draw using only
  1724. the CIRCLE statement and no other graphic statements. You save a lot of time
  1725. and calculation effort because the program does not have to compute the
  1726. coordinates of the hands and minute divisions.
  1727.  
  1728.     REM 1.3.5 Analog Clock.
  1729.     pi=3.1415926#
  1730.     f=.5 'aspect ratio'
  1731.     REM Draw circle.
  1732.     FOR i = .0001 TO 2*pi STEP pi/30
  1733.     CIRCLE (100,100),97,1,i,i,f
  1734.     NEXT i
  1735.     REM Hours marks
  1736.     FOR i = .0001 TO 2*pi STEP pi/6
  1737.     CIRCLE (100,100),93,1,i,i,f
  1738.     CIRCLE (100,100),90,1,i,i,f
  1739.     NEXT i
  1740.     st:  INPUT "Hour    ";hour
  1741.     IF hour > 12 GOTO st
  1742.     INPUT " Minutes  ";minutes
  1743.     hangle = -((12-hour)*60-minutes)*pi/360-pi/2.0001
  1744.     mangle = -(60-minutes)pi/30-pi/2.0001
  1745.     IF hangle <-2*pi THEN hangle = hangle + 2*pi
  1746.     IF mangle <-2*pi THEN mangle = mangle + 2*pi
  1747.     REM Hands
  1748.     CIRCLE (100,100),85,2,mangle,-mangle,f
  1749.     CIRCLE (100,100),70,3,hangle,-hangle,f
  1750.     ON TIMER(60) GOSUB Timeout
  1751.     TIMER ON
  1752.     WHILE 1:WEND
  1753.     Timeout:
  1754.     REM Delete old hands.
  1755.     CIRCLE (100,100),70,0,hangle,-hangle,f
  1756.     CIRCLE (100,100),85,0,mangle,-mangle,f
  1757.     hangle = hangle + pi / 360
  1758.     mangle = mangle + pi / 30
  1759.     IF hangle > 0 THEN hangle = hangle -2*pi
  1760.     IF mangle > 0 THEN mangle = mangle - 2*pi
  1761.     REM New Hands.
  1762.     CIRCLE (100,100),85,2,mangle,-mangle,f
  1763.     CIRCLE (100,100),70,3,hangle,-hangle,f
  1764.     RETURN
  1765.  
  1766. The TIMER statement makes sure that we call the subroutine every minute 
  1767. that updates the clock. This statement lets you bypass interrupt programming
  1768. which is something that you may not be familiar with. This method is much 
  1769. more comfortable to use than the usual way of interrupt programming in 
  1770. AmigaBASIC.
  1771.  
  1772.                 PAGE 28
  1773.  
  1774. ----------------------------------------------------------------------------
  1775.  
  1776. Instead of the endless loop, WHILE 1: WEND, you could substitute your main
  1777. program. In this case it would be useful to place the clock within its 
  1778. own window.
  1779.  
  1780.                 PAGE 29
  1781.  
  1782. ----------------------------------------------------------------------------
  1783.  
  1784. 1.4 AREA FILL.
  1785.  
  1786. So far you have learned several ways to draw different shapes. You used the 
  1787. LINE statement to quickly draw colored rectangles on the screen.
  1788.  
  1789. The CIRCLE statement does not have a built in fill function so we stepped 
  1790. ahead a bit and used the PAINT statement. This is the statement we are now
  1791. going to look at in detail.
  1792.  
  1793.         ---------------------------------------------
  1794.  
  1795. 1.4.1 THE PAINT STATEMENT.
  1796.  
  1797. To paint simply means to fill an area with colour. The PAINT statement does 
  1798. this with amazing speed. To do this, first specify the location of a pixel 
  1799. inside the shape you want to paint. If the shape and fill colours are not the
  1800. same, add the shape colour at the end of the statement. The shape colour 
  1801. tells the computer where to stop painting. You can specify the location using
  1802. either relative or absolute coordinates. Using a relative address after the
  1803. CIRCLE statement is easy because the graphic cursor is still located in the 
  1804. center of the circle. You can see how easily we fill circles in the next 
  1805. program.
  1806.  
  1807.     REM 1.4.1 Fill Demo.    
  1808.     SCREEN 1,320,200,5,1
  1809.     WINDOW 2,,(0,0)-(311,185),16,1
  1810.     RANDOMIZE TIMER
  1811.     WHILE INKEY$ = ""
  1812.         f = INT(RND*32)
  1813.         CIRCLE (RND*311,RND*185),RND*100,f
  1814.     WEND
  1815.     WINDOW CLOSE 2
  1816.     SCREEN CLOSE 1
  1817.  
  1818. Compared to the rectangle program using LINE, this program fills in the 
  1819. colour a little slower. The CIRCLE statement is one reason why this happens.
  1820. However, the PAINT statement fills in colour slower than the LINE statement 
  1821. with a box fill function. This is because the PAINT statement has to check 
  1822. every pixel for the shape border before painting.
  1823.  
  1824. You should be very careful when using PAINT. If the border of the area you
  1825. want filled has even one hole in it, the entire screen can be painted. The 
  1826. same thing will happen if you specify a window type smaller than 16 (see
  1827. PAINT in the BASIC handbook). In this case, if the shape passes outside the
  1828. right window border, the entire window is filled. To test this, change the
  1829. 16 in the last program to a zero.
  1830.  
  1831.                 PAGE 30
  1832.  
  1833. --------------------------------------------------------------------------
  1834.  
  1835. 1.4.2 ANOTHER SOLUTION. AREA AND AREAFILL.
  1836.  
  1837. There is another way to fill an area besides using LINE and PAINT. Unlike 
  1838. with PAINT, we do not need a border shape, instead we need single pixels as
  1839. corner points.
  1840.  
  1841. There are two statements used in this method. The first statement AREA, sets 
  1842. all the corners. This statement is easier to use than PSET because no 
  1843. colours are needed.
  1844.  
  1845.     AREA (10,30)
  1846.     AREA (199,140)
  1847.     AREA STEP (200,-30)
  1848.  
  1849. As you can see, the AREA statement is used relatively.
  1850.  
  1851. The second statement, AREAFILL, tells the computer to paint the defined area.
  1852.  
  1853.     AREAFILL
  1854.  
  1855. After entering the four statements you should see a white triangle on your
  1856. screen (WHAT FUCKIN FOUR STATEMENTS?!?!?!).
  1857.  
  1858. Because the power of these statements is their ability to create figures 
  1859. with many corners, the triangle does not completely demonstrate this power.
  1860.  
  1861. The sequence of the corners you specify will determine what your figures will
  1862. look like. Although the order of three points does not make much difference,
  1863. with 4 points it is possible to have three different figures using the same
  1864. coordinates.
  1865.  
  1866.     REM 1.4.2A Three Possible
  1867.     AREA (10,10)
  1868.     AREA (30,140)
  1869.     AREA (60,100)
  1870.     AREA (50,20)
  1871.     AREAFILL
  1872.     WHILE INKEY$="": WEND
  1873.     CLS
  1874.     AREA (10,10)
  1875.     AREA (60,100)
  1876.     AREA (50,20)
  1877.     AREA (30,140)
  1878.  
  1879.                 PAGE 31
  1880.  
  1881. ----------------------------------------------------------------------------
  1882.  
  1883.     AREAFILL
  1884.     WHILE INKEY$="": WEND
  1885.     CLS
  1886.     AREA (10,10)
  1887.     AREA (60,100)
  1888.     AREA (30,140)
  1889.     AREA (50,20)
  1890.     AREAFILL
  1891.  
  1892. The larger the number of corners, the greater the number of possible 
  1893. connecting lines. A pentagram, which has 5 points and can be drawn by hand in
  1894. one motion, is a good example of this:
  1895.  
  1896.     REM 1.4.2B PENTAGRAM
  1897.     AREA (100,20)
  1898.     AREA (140,100)
  1899.     AREA (20,45)
  1900.     AREA (180,40)
  1901.     AREA (40,110)
  1902.     AREAFILL
  1903.  
  1904. You will notice that in the completed star only the points are white but the
  1905. centre is still blue. To explain this we will use the same program again only
  1906. slightly changed:
  1907.  
  1908.     REM 1.4.2C FRAMING BY DRAWING TWICE
  1909.  
  1910.     FOR i = 0 TO 3
  1911.       AREA (10,30)
  1912.       AREA (199,140)
  1913.       AREA STEP (200,-30)
  1914.     NEXT
  1915.     AREAFILL
  1916.  
  1917. By changing the program we have set each corner twice and filled each area 
  1918. twice with AREAFILL. You might think that drawing twice works better, but 
  1919. this is not true. Instead of a filled area we only see the border.
  1920.  
  1921. The pentagram is much the same. Like the triangle above, the pentagram's 
  1922. centre is outlined twice and filled twice. Painting the same area a second 
  1923. time has the same result as erasing it.
  1924.  
  1925. A figure with only 5 corners isn't very complicated. But if we create a 
  1926. figure using 19 corners, it is difficult to detect all the corner points.
  1927. By using random values, you can create figures that resemble modern art.
  1928.  
  1929.                 PAGE 32
  1930.  
  1931. ----------------------------------------------------------------------------
  1932.  
  1933.     REM 1.4.2D 19 CORNERS.
  1934.     WINDOW 1, "Modern Art",(0,0)-(615,185),15    
  1935.     Start:
  1936.     CLS
  1937.     RANDOMIZE TIMER
  1938.     FOR i = 0 TO 18
  1939.     AREA (RND+61,RND*185)
  1940.     NEXT i
  1941.     AREAFILL
  1942.     WHILE INKEY$="": WEND
  1943.     GOTO Start:
  1944.  
  1945. Since AREAFILL can only work on a maximum of 19 corners, if you try to set
  1946. more than this, nothing will be displayed on the screen. After and AREAFILL
  1947. statement, all the corner points are removed from memory and you can specify
  1948. new ones.
  1949.  
  1950.  
  1951. 1.4.2.1 DIFFERENT MODES OF AREAFILL.
  1952.  
  1953. AREAFILL has two different modes. This first mode, which you already know
  1954. because we have been using it, always fills an area with the default
  1955. foreground colour. In our example we used white but you can change this by
  1956. using the COLOR statement.
  1957.  
  1958.     COLOR 2
  1959.  
  1960. Once this statement is executed, the next area is filled with black. This is
  1961. the only way you can have a direct effect on the colour of an area. Since it
  1962. is the default mode, this mode does not require a lot of exlpanation. You
  1963. can specify this mode with a trailing zero:    
  1964.  
  1965.     AREAFILL 0
  1966.  
  1967. The second mode of AREAFILL inverts the area instead of filling the area.
  1968.  
  1969.     REM 1.4.2.1A Invert Demo.
  1970.     WINDOW 1,"INVERT DEMO",(0,0)-(615,185),15
  1971.     PRINT "This is a Test!"
  1972.     PRINT "All points inside"
  1973.     PRINT "the triangle will be"
  1974.     PRINT "Inverted!!"
  1975.     CIRCLE (100,100),90,2
  1976.     PAINT STEP (0,0),3,2
  1977.     AREA (20,0)
  1978.     AREA (180,45)
  1979.     AREA (40,100)
  1980.     AREAFILL 1
  1981.  
  1982. To indicate this mode enter a one after the AREAFILL statement. For each 
  1983. pixel on the screen there is a series of bits in memory that specify it's
  1984. colour register. When we invert a pixel, each bit value changes to it's
  1985. opposite value. If a bit was equal to one it changes to zero and if it was
  1986. zero it changes to one. You can calculate the colour register change to a 
  1987. pixel like this:
  1988.  
  1989.     newcolor = (2^depth-1)=oldcolour
  1990.  
  1991.                 PAGE 33
  1992.  
  1993. -------------------------------------------------------------------------
  1994.  
  1995. The following program demonstrates how fast these program changes can
  1996. take place:
  1997.  
  1998.     REM 1.4.2.1B SPEED
  1999.     WINDOW 1,"SPEED TEST",(0,0)-(611,185),15
  2000.     LOCATE 10,4
  2001.     PRINT "SPEED IS NOT A MAGIC TRICK!"
  2002.     WHILE INKEY$=""
  2003.     FOR i = 0 TO 2
  2004.         AREA (RND*611,RND*185)
  2005.     NEXT i
  2006.     AREAFILL 1
  2007.     WEND
  2008.  
  2009. This program uses random corner points for a triangle and inverts everything 
  2010. inside it. The loop repeats and creates many triangles on top each other in
  2011. blue and orange. The result is a screen full of blue and orange checks. The
  2012. longer the program runs, the more difficult it is to identify the individual
  2013. shapes.
  2014.  
  2015.         ---------------------------------------------
  2016.  
  2017. 1.4.3 PATTERNS.
  2018.  
  2019. When a computer fills an area, it sets one pixel after another until the area
  2020. is filled with the selected colour. Besides performing this type of area fill
  2021. the Amiga can also fill an area with a pattern designed by you.
  2022.  
  2023. Patterns can improve a graphic image or make part of the picture stand out. 
  2024. You can also create shadows and build textured walls easily with patterns.
  2025.  
  2026. Besides patterned areas, you can also draw patterned lines.
  2027.  
  2028. Both patterns and patterned line require the same statement. Since the 
  2029. format is much the same for both, we will discuss patterned line first.
  2030.  
  2031.         --------------------------------------------
  2032.  
  2033. 1.4.3.1 PATTERN CREATION.
  2034.  
  2035. To create a pattern for a line, we use a 16 bit mask composed of 16 binary
  2036. numbers (ones and zeros). Each value of one in the mask equals a set pixel 
  2037. in the pattern and each zero equals and empty position.
  2038.  
  2039.                 PAGE 34
  2040.  
  2041. ----------------------------------------------------------------------------
  2042.  
  2043. After 16 pixels, the mask pattern repeats. Therefore you can only draw where
  2044. a mask bit is equal to one. This is similar to using a drawing template 
  2045. because you can only draw where there is a hole.
  2046.  
  2047. Since AmigaBASIC cannot manipulate binary numbers, we have to convert the 
  2048. binary mask value to hexadecimal. You could also convert the mask to decimal
  2049. but this is more complicated. To convert to hexadecimal we have to work with 
  2050. four bits at a time. Our mask could look like this:
  2051.  
  2052.     1011  0010  0000 1111
  2053.  
  2054. We convert each four bit block separately. To do this, we take the first bit
  2055. and multiply it by 8, the second bit and multiply it by 4 and it add to the
  2056. first. We then multiply the third bit by two and add, and then the last bit.
  2057. The result of this operation is a number between 0 and 15. In hexadecimal,
  2058. the numbers 10 thru 15 are converted to the letters A thru F. With our sample
  2059. mask the conversion looks like this :
  2060.  
  2061.     1*8 + 0*4 + 1*2 + 1   = B (11)
  2062.     0*8 + 0*4 + 1*2 + 0   = 2
  2063.     0*8 + 0*4 + 0*2 + 0   = 0
  2064.      1*8 + 1*4 + 1*2 + 1   = F (15)
  2065.  
  2066. By vertically reading the end of the lines above we have B20F. We can try 
  2067. this out in our next program:
  2068.  
  2069.     REM 1.4.3.1 PAtterned lines
  2070.     PATTERN &HB20F
  2071.     LINE (0,0)-(614,185)
  2072.     LINE (20,30)-(104,105),2,B
  2073.  
  2074. As demonstrated, our pattern works not only on lines, but also on rectangles.
  2075. The label "&h" in front of the mask identifies the number as a hexadecimal 
  2076. value.                
  2077.  
  2078.         ------------------------------------------------
  2079.  
  2080. 1.4.3.2 PATTERNED AREAS.
  2081.  
  2082. The pattern format for areas is similar to the format for line patterns. The
  2083. main difference is that areas are two dimensional. Because of this, you have
  2084. to stack many 16 bit masks, one on top of the other, to build an area pattern.
  2085. These masks are assigned using an array variable with the PATTERN variable.
  2086.  
  2087.                 PAGE 35
  2088.  
  2089. ------------------------------------------------------------------------------
  2090.  
  2091. The pattern for lines is the first parameter. The pattern for the areas is 
  2092. the second parameter and defined in an integer array variable.
  2093.  
  2094.     REM 1.4.3.2 Pattern Maker.
  2095.     DEFINT a
  2096.     OPTION BASE 1
  2097.     DIM a(8)
  2098.     FOR i = 1 TO 8
  2099.     READ a(i)
  2100.     NEXT i
  2101.     PATTERN ,a
  2102.     COLOR 3,1
  2103.     LINE (0,0)-(614,185),,bf
  2104.     WHILE INKEY$="": WEND
  2105.     COLOUR 1,0
  2106.     CLS
  2107.     DATA &H0,&H7FFF,&H7FFF,&H7FFF
  2108.     DATA &H0,&HFF7F,&HFF7F,&HFF7F
  2109.  
  2110. The first thing you should do is make your array values all short integers.
  2111. This means only numbers between -32768 and 32767 or in hexadecimal 0 to FFFF.
  2112. If the variable type is wrong, you can create an error condition. To prevent
  2113. this, we declare the array as short integer using DEFINT at the beginning of
  2114. the program.
  2115.  
  2116. The DIM instruction tells PATTERN how many rows are in the pattern. You must
  2117. dimension the array even if there are less than 10 elements. The number of
  2118. array elements has to be equal to a power of two (1,2,4,8...). Should there
  2119. be one or more less, you will get an "illegal function call" error. With 
  2120. normal arrays, you have to use the default array starting value of zero, 
  2121. such as 0-3,0-7 etc. The ending index value is always smaller than the power
  2122. of two. Or you can use:
  2123.  
  2124.     OPTION BASE 1
  2125.  
  2126. to set the default starting value of all arrays to one.
  2127.  
  2128.         -------------------------------------------------
  2129.  
  2130. 1.4.3.3 PATTERN DESIGN IN A PROGRAM.
  2131.  
  2132. As you saw above, calculating the pattern values yourself is a lot of work.
  2133. But when you have a computer that can do the work for you, why should you
  2134. do it?
  2135.  
  2136. All you need is a small program that understands the binary pattern mask and
  2137. converts it into hexadecimal or decimal. Since AmigaBASIC does not recognise
  2138. binary, we have written a small subroutine. This subroutine converts 
  2139. character strings into short integers (numbers that memory sees as two bytes).
  2140. In the character string, you represent each zero with a space and any other 
  2141. character equals a one. We selected the left Amiga button as the shape for 
  2142. our pattern:
  2143.                 
  2144.                 PAGE 36
  2145.  
  2146. ----------------------------------------------------------------------------
  2147.  
  2148.     REM 1.4.3.3 DESIGN IN LISTING.
  2149.     WINDOW,1,"DESIGN PATTERNS",(0,0)-(617,185),15
  2150.     OPTION BASE 1
  2151.     a=8
  2152.     DIM f$(a)
  2153.     REM    0123456789ABCDEF
  2154.     f$(1)="            *** "
  2155.     f$(2)="           **** "
  2156.     f$(3)="         *  *** "
  2157.     f$(4)="       *    *** "
  2158.     f$(5)="      ********* "
  2159.     f$(6)="     **     *** "
  2160.     f$(7)="   *****   *****"
  2161.     f$(8)=""
  2162.     REM    0123456789ABCDEF
  2163.     CALL changeformat(f$(),a)
  2164.     CIRCLE(400,140),100
  2165.     PAINT STEP (0,0),2,1
  2166.     AREA (150,160)
  2167.     AREA (500,100)
  2168.     AREA (570,170)
  2169.     AREA FILL 1
  2170.     MOUSE ON
  2171.     WHILE INKEY$=""
  2172.     IF MOUSE(0) <>0 THEN
  2173.         b=MOUSE(1)
  2174.         c=MOUSE(2)
  2175.         IF b>0 AND b<600 AND c>0 AND c<172 THEN
  2176.         LINE (b,c)-(b+4,c+4),1,bf
  2177.         END IF
  2178.     END IF
  2179.     WEND
  2180.  
  2181.     SUB changeformat (fd$(1),g) STATIC
  2182.     DIM fd%(g)
  2183.     FOR i = 1 TO g
  2184.         fd$(i)=fd$(i)+SPACE$(16)
  2185.         FOR j = 1 TO 3
  2186.         h=0
  2187.         FOR k = 1 TO 3
  2188.             IF MID$(fd$(i),j*4+k+1,1)<>" " THEN h=h+2^(3-k)
  2189.             NEXT k
  2190.         fd%(i)=fd%(i)+VAL("&h"+HEX$(h*2^(4*(3-j))))
  2191.         NEXT j
  2192.         PRINT i, HEX$(fd%(i)),fd%(i)
  2193.     NEXT i
  2194.     PATTERN ,fd%
  2195.     END SUB
  2196.  
  2197. First we convert the character strings from spaces and asterisks into a 
  2198. pattern. Then we use this pattern to fill a circle and a triangle. The 
  2199. program also allows you to draw with the mouse, using the defined pattern.
  2200. When you press the mouse button you can draw a 4*4 pixel sized rectangle
  2201. filled with the pattern.
  2202.  
  2203.                 PAGE 37
  2204.  
  2205. ----------------------------------------------------------------------------
  2206.  
  2207. Two parameters are passed into the subroutine that converts the character 
  2208. strings into hexadecimal values. The first parameter is the array where the
  2209. mask will be stored and the second parameter is the number of elements in the
  2210. array. We perform the conversion using the principles we explained earlier.
  2211. The subroutine then passed the pattern to the PATTERN statement.
  2212.  
  2213. Since calculating a pattern mask every time you run a program can be 
  2214. troublesome, the above program is very useful as a pattern editor. For 
  2215. example, change the Amiga-A pattern to any pattern you want to use. If you
  2216. want a different pattern , change the strings again. The calculated pattern 
  2217. values are printed on the screen in decimal and hexadecimal. When the pattern 
  2218. generated is the one you want, write down the values and insert them in your
  2219. own program.
  2220.  
  2221.         -------------------------------------------------
  2222.  
  2223. 1.4.3.4 PATTERNS AND THE CURSOR.
  2224.  
  2225. Patterns are supposed to be used with fill functions and should only affect
  2226. fill functions. However, a side effect occurs when defining a pattern. The
  2227. cursor is also changed. For example, in the previous program, the cursor
  2228. appeated after the program printed the pattern values in the output window,
  2229. but only as a small point. If you press the space bar you would see a dotted
  2230. line instead of the normal pattern. These dots come from the Amiga-A pattern.
  2231. If this changed cursor is disturbing, you can recover the normal cursor by
  2232. adding the following lines to the program.
  2233.  
  2234.     REM Cursor REset
  2235.     DIM norm%(2)
  2236.     norm%(1) = &HFFFF
  2237.     norm%(2) = &HFFFF
  2238.     PATTERN ,norm%
  2239.  
  2240. It is very important that you use the statement "OPTION BASE 1" before 
  2241. running these program lines. If you do not use OPTION BASE, you must decrement
  2242. all array values by one.
  2243.  
  2244. Of course, you could do the opposite and change the cursor on purpose. You 
  2245. can make the cursor disappear when using INPUT or change it to a dashed line.
  2246. To create a dashed line make the value or norm%(2) in the last program equal
  2247. to zero. A half block cursor requires an array with eight elements. You
  2248. set the first four values to zero and the last four to &HFFFF for a bottom 
  2249. half block cursor. To make a top block cursor just switch the four first and
  2250. last values.
  2251.  
  2252.                 PAGE 38
  2253.  
  2254. ----------------------------------------------------------------------------
  2255.  
  2256. For a bottom half block cursor. To make a top block cursor, just switch
  2257. the four first and last values.
  2258.  
  2259.                  ----------------------------------------
  2260.  
  2261. 1.4.3.5              BRINGING IT TOGETHER
  2262.  
  2263. you can write some fantastic programs using pattern filled areas. The
  2264. program below is a good example of this.
  2265.  
  2266.     REM 1.4.3.5A Stars and Stripes
  2267.     DEFINT a-z
  2268.     OPTION BASE 1
  2269.     DIM a(a6)
  2270.     SCREEN 1,320,200,5,1
  2271.     WINDOW 2,,(0,0)-(311,185),16,1
  2272.     FOR i= 1 TO 16
  2273.         READ a(1)
  2274.     NEXT i
  2275.     PAINT (0,0),2
  2276.     LINE (16,16)-(260,146),9,bf
  2277.     FOR i= 0 TO 5
  2278.         LINE(16,26+i*20)-(260,36+i*20),1,bf
  2279.     NEXT i
  2280.     PATTERN ,a
  2281.     LINE (16,16)-(111,80),1,bf
  2282.     DATA 0,1536,3840,-16,16320,8064
  2283.     DATA 6528,0,0,96,240,4095,1020
  2284.     DATA 504,408,0
  2285.     WHILE INKEY$="": WEND
  2286.     WINDOW CLOSE 2
  2287.     SCREEN CLOSE 1
  2288.     
  2289. An American flag appears shortly after starting this program. We defined
  2290. the stars in a pattern containing two stars, one above the other. The top
  2291. star is centered and the other is slightly offset so the rows are not
  2292. vertically aligned.
  2293.  
  2294. As we hinted above, another possible use for patterns is to create 3-D
  2295. effects. We have a small demonstration program to illustrate this:
  2296.  
  2297.     REM 1.4.3.5B 3-D
  2298.     DEFINT a-z
  2299.     REM 3-D Cubes
  2300.     OPTION BASE 1
  2301.     DIM c(4)
  2302.     SCREEN 1,320,200,3,1
  2303.     WINDOW 2,,(0,0)-(311,185),16,1
  2304.     COLOR 0,1
  2305.     CLS
  2306.     REM Pattern
  2307.     c(1)=&H1010
  2308.  
  2309.                                   PAGE 39
  2310.  
  2311. ---------------------------------------------------------------------------
  2312.  
  2313.     c(2)=&H4040
  2314.     c(3)=&H101
  2315.     c(4)=&H404
  2316.     PATTERN ,c
  2317.     h=94
  2318.     x=68
  2319.     y=x/2
  2320.     REM Large Cube
  2321.     AREA (60,44)
  2322.     AREA STEP (x,-y)
  2323.     AREA STEP (x,y)
  2324.     AREA STEP (0,h)
  2325.     AREA STEP (-x,y)
  2326.     AREA STEP (0,-h)
  2327.     AREAFILL
  2328.     SWAP c(1),c(4)
  2329.     SWAP c(2),c(3)
  2330.     PATTERN ,c
  2331.     AREA STEP (0,0)
  2332.     AREA STEP (-x,-y)
  2333.     AREA STEP (0,h)
  2334.     AREA STEP (x,y)
  2335.     AREAFILL
  2336.     REM Small Cube
  2337.     COLOR 4
  2338.     AREA STEP (0,-h/2)
  2339.     AREA STEP (x/2,-y/2)
  2340.     AREA STEP (0,-h/2)
  2341.     AREA STEP (-x/2,-y/2)
  2342.     AREA STEP (-x/2,y/2)
  2343.     AREA STEP (0,h/2)
  2344.     AREAFILL
  2345.     SWAP c(1),c(4)
  2346.     SWAP c(2),c(3)
  2347.     PATTERN ,c
  2348.     AREA STEP (0,0)
  2349.     AREA STEP (x/2,-y/2)
  2350.     AREA STEP (0,-h/2)
  2351.     AREA STEP (-x/2,y/2)
  2352.     AREAFILL
  2353.     WHILE INKEY$="": WEND
  2354.     WINDOW CLOSE 2
  2355.     SCREEN CLOSE 1
  2356.  
  2357. You will see a 3-D cube standing on one of its corners. It appears that
  2358. either a small cube is missing or is stacked on top.
  2359.  
  2360. The patterns that we used to create the intersecting pieces are almost the
  2361. same. The only difference is the order we assign the values. To change from
  2362. one pattern to another, just reverse the order of the variables. In this
  2363. program we used to SWAP-assignments to take care of this.
  2364.  
  2365.                                 PAGE 40
  2366.  
  2367. ---------------------------------------------------------------------------
  2368.  
  2369. 1.5  MEDLEY OF COLORS
  2370.  
  2371. The Amiga provides a palette of 4096 colors. If you use pure BASIC you can
  2372. only use 32 colors at a time (we'll show you how to use more later). The
  2373. specific colors are stored in the color registers. When you use a
  2374. statement, you are not selecting which color to use but which color
  2375. register to get the color from.
  2376.  
  2377. You cannot use all 32 colors in any type of screen. The number of possible
  2378. colors depends on the depth of your screen. A normal Workbench screen has a
  2379. depth of two, which allows you four colors. For every pixel there are two
  2380. bits in memory which determine those four colors. 
  2381.  
  2382.     00    Color register 0
  2383.     01    Color register 1
  2384.     10    Color register 2
  2385.     11    Color register 3
  2386.  
  2387. To display 32 colors you need five bits per pixel, but first you have to
  2388. open a new screen with a depth of five:
  2389.  
  2390.     SCREEN 1,320,200,5,1
  2391.     WINDOW 2,"TITLE",(0,0)-(311,185),16,1
  2392.  
  2393. Now you could use all the statements you have learned so far with 32
  2394. colors.
  2395.  
  2396. Of the 32 colors available, you can select one for the foreground and one
  2397. for the background.
  2398.  
  2399.     COLOR 1,0
  2400.  
  2401. These are the two default values. The first sets the foreground color and
  2402. the second sets the background color. All the graphic statements will use
  2403. these two colors. As longs as you leave the color parameter off, even PSET
  2404. will use the default foreground color, and PRESET will use the default
  2405. background color.
  2406.  
  2407. Changing the foreground and/or background, color does not instantly change
  2408. the screen colors. Using the CLS statement makes the new colors take
  2409. effect.
  2410.  
  2411.                                  PAGE 41
  2412.  
  2413. ---------------------------------------------------------------------------
  2414.  
  2415.     COLOR 2,3
  2416.     CLS
  2417.  
  2418. The above statement gives you an orange screen with a black foreground
  2419. color. 
  2420.  
  2421.         ----------------------------------------
  2422.  
  2423. 1.5.1             THE COMPLETE PALETTE
  2424.  
  2425.  
  2426. Most of the time you will probably want a completely different set of
  2427. colors in you program instead of the 32 default colors. To do this, you
  2428. have to change the colors in the color registers.
  2429.  
  2430. Every color is composed of three values which set the read, green and blue
  2431. of the color(RGB). Each of these values has a range from one to 4096.
  2432.  
  2433. The BASIC statement use to change the colors is PALETTE. You must specify
  2434. the RGB(red, green and blue) values and which color register to change. The
  2435. RGB color division must be a number between zero and one.
  2436.  
  2437.     PALETTE 0,.75,1,0
  2438.  
  2439. This line sets a neon yellow background. This color is a mix of red and
  2440. yellow, blue is not used. To set the normal blue background:
  2441.  
  2442.     PALETTE 0,0,.3,.6
  2443.  
  2444. Setting the red to one(1) and the other ranges to zero gives you red. This
  2445. procedure works the same for the other two ranges.
  2446.  
  2447.         ----------------------------------------
  2448.  
  2449. 1.5.2             CHANGING RGB COLORS
  2450.  
  2451. You can find any color you want by experimenting with the three color
  2452. ranges. However, finding a specific color with this method could be tiring.
  2453. The following program allows you to search for and find your target color.
  2454. You can change all three ranges while the program is running and quickly
  2455.  
  2456.                                PAGE 42
  2457.  
  2458. ----------------------------------------------------------------------------
  2459.  
  2460. find your desired combination. The results are visible on the screen at the
  2461. same time.
  2462.  
  2463.     REM 1.5.2 ColorConstructor
  2464.     SCREEN 1,320,200,2,1
  2465.     WINDOW 2,"ColorConstructor",(0,0)-(297,185),31,1
  2466.     LINE (200,20)-(300,150),3,bf
  2467.     LOCATE 5
  2468.     PRINT "> '4'   '5'   '6'"
  2469.     LOCATE 16
  2470.     PRINT "< '1'   '2'   '3'"
  2471.     LOCATE 10
  2472.     PRINT "   R   G   B"
  2473.     r=1:g=.5:b=0    ' orange
  2474.     WHILE 1
  2475.     LOCATE 11
  2476.     PRINT USING "  #.##";r;g;b
  2477.     PALETTE 3,r,g,b
  2478.     WHILE A$=""
  2479.      A$=INKEY$
  2480.     WEND
  2481.      IF A$<>"" THEN
  2482.       IF A$="1" and r>=.0666 THEN r=r-.06666            
  2483.       IF A$="4" and r>=.9333 THEN r=r+.06666            
  2484.       IF A$="2" and g>=.0666 THEN g=g-.06666            
  2485.       IF A$="5" and g>=.9333 THEN g=g+.06666            
  2486.       IF A$="3" and b>=.0666 THEN b=b-.06666            
  2487.       IF A$="6" and b>=.9333 THEN b=b+.06666            
  2488.      END IF
  2489.     WEND
  2490.  
  2491. You can change the color ranges by using the 1-6 keys. The numeric keypad
  2492. is perfectly arranged for changing color ranges. The 4 key raises and the 1
  2493. key lowers it. The 5 and 2 keys raise and lower the green range, and the 6
  2494. and 3 keys raise and lower the blue range.
  2495.  
  2496. The color range will increase and decrease by a value of 0.0666 or 1/15.
  2497. This insures a color range with every keypress.
  2498.  
  2499. You can also change the mouse pointer colors with the PALETTE. The effected
  2500. registers are 17,18 and 19. Try it out.
  2501.  
  2502.         ----------------------------------------
  2503.  
  2504. 1.5.3             THE OPPOSITE OF PALLETTE
  2505.  
  2506. In many programs it is very important to know what colors are in the
  2507. palette. However, there is no statement in BASIC that performs the opposite
  2508. of PALETTE. Again we will step ahead a little and get out our data directly
  2509.  
  2510.                      PAGE 43
  2511.  
  2512. ----------------------------------------------------------------------------
  2513.  
  2514. from memory. We will explain later, when we leave pure BASIC, how to
  2515. detemine the address of the color table. 
  2516.  
  2517. Since the functions assigned at the beginning of the program take care of
  2518. any addresses or PEEKs, you do not have to concern yourslef with these. You
  2519. just have to provide the color register number to the function. There are
  2520. three functions, one for each RGB color range.
  2521.     
  2522.     REM 1.5.3 Palette-Opposite
  2523.     SCREEN 1,320,200,5,1
  2524.     WINDOW 2,,,16,1
  2525.     DEF FNcolortab=PEEKL(PEEKL(PEEKL(WINDOW(7)+46)+48)+4)
  2526.     DEF FNred(f)=(PEEKW(FNcolortab+2*f) AND 3840)/3840
  2527.     DEF FNgreen(f)=(PEEKW(FNcolortab+2*f) AND 240)/240
  2528.     DEF FNblue(f)=(PEEKW(FNcolortab+2*f) AND 15)/15
  2529.     PRINT "RGB Color Values:"
  2530.     FOR i = - TO 31
  2531.       LOCATE 5+i MOD 16,1+INT(i/16)*20
  2532.         COLOR i
  2533.       PRINT USING "##";i,
  2534.         COLOR 1
  2535.       PRINT USING " #.##";FNred(i);FNgreen(i);FNblue(i)
  2536.     NEXT i
  2537.     WHILE INKEY$="":WEND
  2538.     WINDOW CLOSE 2
  2539.     SCREEN CLOSE 1
  2540.  
  2541. This program prints out the color values for evry color. The color register
  2542. and color are listed in front of the three ranges.
  2543.  
  2544.         ----------------------------------------
  2545.  
  2546. 1.5.4            ANIMATION USING COLOR
  2547.  
  2548. Now we'll show you away to make functions from the last program useful. You
  2549. can easily animate a picture by repeatedly swapping several colors. This
  2550. color cycling trick may be familier to you because paint programs, such as
  2551. GraphiCraft and Deluxe Paint, use it. You can magically display moving
  2552. rivers or similar actions with this method. With some porgramming, this
  2553. color swapping is possible in BASIC. However, you should keep the number of
  2554. colors being swapped as small as possible because of BASIC's slowness. If
  2555. you use too many colors, the cycling will be slower, causing a jerky and
  2556. ragged look. 
  2557.  
  2558.     REM 1.5.4 Palette-Opposite Expanded
  2559.     SCREEN 1,320,200,5,1
  2560.     WINDOW 2,,,16,1
  2561.     PALETTE 0,0,.5,0
  2562.     PALETTE 28,0,.35,.72
  2563.  
  2564.                 PAGE 44
  2565.  
  2566. ----------------------------------------------------------------------------
  2567.  
  2568.     PALETTE 29,0,.35,1
  2569.     PALETTE 30,0,.5,1
  2570.     PALETTE 31,0,.6,1
  2571.     DEF FNcolortab(PEEKL(PEEKL(WINDOW(7)+46)+48+4)
  2572.     DEF FNred(f)=(PEEKW(FNcolortab+2*f) AND 3840)/3840
  2573.     DEF FNgreen(f)=(PEEKW(FNcolortab+2*f) AND 240)/240
  2574.     DEF FNblue(f)=(PEEKW(FNcolortab+2*f) AND 15)/15
  2575.     f1=28:f2=31
  2576.     FOR j=0 TO 311 STEP 4
  2577.     FOR i=0 to 3 STEP .5
  2578.       LINE (j+i,120+j/8)-(J+i-4,140+j/8),28+i
  2579.       LINE (j+i+1,120+j/8)-(J+i-3,140+j/8),28+i
  2580.     
  2581.     NEXT i
  2582.     NEXT j
  2583.     rotation:
  2584.     r1=FNred(f2)-.03
  2585.     g1=FNgreen(f2)-.03
  2586.     b1=FNblue(f2)-.03
  2587.     FOR i=f1 TO f2
  2588.       r=FNred(i)-.03
  2589.       g=FNgreen(i)-.03
  2590.       b=FNblue(i)-.03
  2591.       PALETTE i,r1,g1,b1
  2592.       r1=r
  2593.       g1=g        
  2594.         b1=b
  2595.     NEXT i
  2596.     GOTO rotation
  2597.  
  2598. This program draws an abstract river. We set the last eight color registers
  2599. to blue for the river.
  2600.  
  2601. In the program routine "rotation" we subtract .03 from the recieved color
  2602. range before using the value with PALETTE. This corrects a calculation
  2603. error for the floating point value, that is between 0 and 15, which we
  2604. received from memory.
  2605.  
  2606.                 PAGE 45
  2607.  
  2608. ----------------------------------------------------------------------------
  2609.  
  2610. 1.6            ALL ABOUT PUT AND GET
  2611.  
  2612. The PUT and GET statements have many uses, which include saving your
  2613. graphcis on disk and working with animation. However, all the PUT and GET
  2614. capabilities have one thing in common: the managment of screen information.
  2615.  
  2616.         ----------------------------------------
  2617.  
  2618. 1.6.1            USING PUT AND GET
  2619.  
  2620. With GET you can read a graphic from a specific region and with PUT you can
  2621. draw it. We store the data in an array variable defined as integer. By
  2622. using values between -32768 and 32767, building the data array is easier.
  2623.  
  2624.     1. Array position = width
  2625.     2. Array position = height
  2626.     3. Array position = depth
  2627.     4. Array position = bit-planes
  2628.  
  2629. Starting with fourth array element are the bit-planes. The depth of a
  2630. graphic detemines how many bits are used for each pixel. The first
  2631. bit-plane contains all the first bits, the second all the second bits, etc.
  2632. This is also why the depth sets the number of bit-planes. The number of
  2633. elements in array will differ greatly depending on the graphics mode, width
  2634. values and height values.
  2635.  
  2636. To store data in integer form, we combine 16 bits of one bit-plane and one
  2637. screen line. Since we cannot store more than this in a short integer, we
  2638. have to devide the width by 16 when assigning array space. If there is a
  2639. remainder(the width did not devide evenly by 16), we have to round off. The
  2640. last pixel of a line is cut off if you do not round off. Now multiply this
  2641. value with the height and depth to get number array elements. You will
  2642. always have the three elements for width, height and depth. The following
  2643. formula will calculate the number of elements required:
  2644.     
  2645.     Arrayspace=3+Height*Depth*INT((width+15)/16)
  2646.  
  2647. The first program in this section simply stores the screen contents with
  2648. GET, clears the screen and restores the old contents.
  2649.  
  2650.                 PAGE 46
  2651.  
  2652. ----------------------------------------------------------------------------
  2653.  
  2654.         REM 1.6.1 Demo for GET and PUT
  2655.         OPTION BASE 1
  2656.         DEFINT f
  2657.         CIRCLE (170,60),110
  2658.         PAINT STEP (0,0),2,1
  2659.         COLOR 1,2
  2660.         LOCATE 5,10
  2661.         PRINT "This demo shows"
  2662.         PRINT "How to store"
  2663.         PRINT "graphics to memory"
  2664.         PRINT "and also how to"
  2665.         PRINT "display them again"
  2666.         PRINT "on the screen!!!!"
  2667.         AREA (140,20)
  2668.         AREA (80,60)
  2669.         AREA (300,80)
  2670.         AREAFILL 1
  2671.         COLOR 1,0
  2672.         REM Save Graphic.
  2673.         x1 = 40: y1 = 10
  2674.         x2=300 : y2 = 120
  2675.         DIM feld(3+2*(y2-y1+1)*INT((x2-x1+16)/16))
  2676.         GET (x1,y1)-(x2,y2),feld
  2677.         REM Redisplay Graphic
  2678.         FOR i = 0 TO 140
  2679.            CLS
  2680.            PUT (i*3,i),feld
  2681.         NEXT i
  2682.  
  2683. The first 20 lines of the above program draw the graphics. We used the top
  2684. left and lower right corners of this image to calculate how much array
  2685. space to dimension.
  2686.  
  2687. We can easily check whether or not our calculation assigned enough space.
  2688. Instead of adding the three required values in the formula, try adding only
  2689. two . As soon as the program starts,an "illegal function call" error will
  2690. appear on the screen. This error will always appear on the screen. This
  2691. error will always appear when you fail to reserve enough space for GET. As
  2692. long as you have plenty of memory, you can never assign too much space.
  2693.  
  2694. This demonstration shows you more than just how these statements work; you
  2695. can also see how fast the graphics move around the screen. The motion is so
  2696. smooth you can even read the moving text. As you have witnessed, moving
  2697. graphics and animation is easy when you use PUT and GET.
  2698.  
  2699.                                 PAGE 47
  2700.  
  2701. ----------------------------------------------------------------------------
  2702.  
  2703. 1.6.2 SAVING TO DISK.
  2704.  
  2705. You have seen how to store screen information in memory using arrays. But
  2706. we cannot just leave the data in memory, because when you turn the computer
  2707. off the data will be lost. In order to permanently keep your graphic, you
  2708. must save it on disk. The following program contains subroutines for saving
  2709. and loading and can be used in other programs.
  2710.  
  2711. This program is also good for painting. When the program starts you have a
  2712. single pixel brush that has four colors. You can save your drawing to disk
  2713. and then load it again to use as a brush.
  2714.  
  2715.         REM 1.6.2 Paint Program
  2716.         OPTION BASE 1
  2717.         DEFINT a-z
  2718.         PRINT "Draw with the mouse"
  2719.         PRINT "When you want to save part"
  2720.         PRINT "Part of your graphic, press the "
  2721.         PRINT "S key. To load a graphic press"
  2722.         PRINT "the L key."
  2723.         PRINT "Press the 'E' key to exit"
  2724.         WHILE a$<>"e"
  2725.            a$=INKEY$
  2726.            WHILE a$=""
  2727.                 IF MOUSE(0)<>0 THEN
  2728.                     PSET(MOUSE(1),MOUSE(2))
  2729.                 END IF
  2730.                 a$=INKEY$
  2731.            WEND
  2732.            IF a$="l" THEN GOSUB picload
  2733.            IF a$="s" THEN GOSUB picsave
  2734.            IF a$>="0" AND a$<"4" THEN COLOR VAL(a$)
  2735.         WEND
  2736.         END
  2737.  
  2738.      picload:
  2739.         DIM fd(10000)
  2740.         WINDOW 2,,(0,0)-(600,0).16
  2741.         INPUT "Load file :";b$
  2742.         IF b$<>"" THEN
  2743.             CALL loader(b$,fd())
  2744.         END IF
  2745.         WINDOW CLOSE 2
  2746.         WHILE INKEY$=""
  2747.             IF MOUSE(0)<>0 THEN
  2748.                 PUT(MOUSE(1),MOUSE(2)),fd
  2749.             END IF
  2750.         WEND
  2751.         ERASE fd
  2752.      RETURN
  2753.  
  2754.                                 PAGE 48
  2755.  
  2756. ----------------------------------------------------------------------------
  2757.  
  2758.      picsave:
  2759.         WINDOW 2,,(0,0)-(600,0).16
  2760.         INPUT "Save file : ";b$
  2761.         IF b$<>"" THEN
  2762.             PRINT "Position the corner points";
  2763.             PRINT "with the mouse";
  2764.       1     IF MOUSE(0)=0 THEN 1
  2765.             ax=MOUSE(1):ay=MOUSE(2)
  2766.       2     IF MOUSE(0)<> 0 THEN 2
  2767.       3     IF MOUSE(0)=0 THEN 3
  2768.             bx = MOUSE(1):by = MOUSE(2)
  2769.             WINDOW CLOSE 2
  2770.             CALL saver(b$,ax,ay,bx,by,2)
  2771.         ELSE
  2772.             WINDOW CLOSE 2
  2773.         END IF
  2774.         RETURN
  2775.  
  2776.         ' The following SUBroutines work without the main program
  2777.  
  2778.         SUB saver (n$,x1,y1,x2,y2,dp) STATIC
  2779.             e=3+(y2-y1+1)*dp*INT((x2-x1+16)/16)
  2780.             DIM graphic%(e)
  2781.             GET (x1,y1)-(x2,y2),graphic%
  2782.             OPEN n$ FOR OUTPUT AS #1
  2783.             FOR i = 1 TO e
  2784.                 WRITE #1,graphic%(i)
  2785.             NEXT i
  2786.             CLOSE #1
  2787.             ERASE graphic%
  2788.         END SUB
  2789.  
  2790.         SUB loader (filename$,graphic%(1)) STATIC
  2791.             OPEN filename$ FOR INPUT AS #1
  2792.             INPUT #1,graphic%(1),graphic%(2),graphic%(3)        
  2793.             e=3+graphic%(3)*graphic%(2)*INT((graphic%(1)+15)/16)
  2794.             FOR i = 4 TO e
  2795.                 INPUT #1,graphic%(i)
  2796.             NEXT i
  2797.             CLOSE 1
  2798.         END SUB
  2799.  
  2800. If you want to save the entire screen, you wont have enough memory
  2801. assigned. To avoid this problem use the following statement once before
  2802. starting the program:
  2803.  
  2804.         CLEAR ,40000
  2805.  
  2806. To be able to load a full screen again you also have to change a variable
  2807. dimension. At the program label PICLOAD raise the DIM statement for fd to
  2808. 15000.
  2809.  
  2810.                                 PAGE 49
  2811.  
  2812. ----------------------------------------------------------------------------
  2813.  
  2814. There are also a few things you must do when you use the load and save
  2815. subroutines in your own programs.
  2816.  
  2817. For the save subroutine, you have to pass the following variables: data
  2818. name, upper left and lower right hand corner coordinates and the depth.
  2819.  
  2820. For the load subroutine you need the data name and an array that is large
  2821. enough to hold the data. To prevent errors, it is much safer to assign an
  2822. array larger than you need.
  2823.  
  2824. You can switch between, and use, load and save routines as often as you
  2825. like. The ERASE statement at the end of the save subroutine handles any
  2826. variable problems. Because variables retain their values between subroutine
  2827. calls, a "duplicate definition" error would appear if we had not used
  2828. ERASE.
  2829.  
  2830. We manage the loading and saving on disk with the standard data file
  2831. handling statements OPEN,INPUT,WRITE and CLOSE. You use OPEN and CLOSE to
  2832. open and close a disk data file. When you open a file you also indicate if
  2833. you are going to read or write data. To write data into a sequential file
  2834. use the WRITE statement. Each data value is sent to the the file one after
  2835. another, like entering characters on the keyboard.
  2836.  
  2837. When you are loading , load the width, height and depth before loading the
  2838. bit-planes. Then calculate the size of the array and determine how many
  2839. elements are loaded.
  2840.  
  2841.                 --------------------------------------------
  2842.  
  2843. 1.6.3   ALTERNATIVE USES FOR PUT
  2844.  
  2845. In the last program you probably noticed an interesting side-effect caused
  2846. by the PUT statement. Passing over an existing image on the screen caused a
  2847. blending of the image. Maybe you also discovered that when you get the same
  2848. graphic twice in the same place, the graphic is erased.
  2849.  
  2850.                 ---------------------------------------------
  2851.  
  2852. 1.6.3.1 DEFAULT MODE OF PUT.
  2853.  
  2854. Both of these effects are side effects of the PUT statement. Instead of
  2855. painting over what is on the screen, PUT links the new pixel with the
  2856. existing one by using XOR. The logic table for XOR look like this:
  2857.  
  2858.                                 PAGE 50
  2859.  
  2860. ----------------------------------------------------------------------------
  2861.  
  2862.         0 XOR 0         = 0
  2863.         0 XOR 1         = 1
  2864.         1 XOR 0         = 1
  2865.         1 XOR 1         = 0
  2866.  
  2867. When two points line up exactly, the pixel is erased. A pixel is drawn only
  2868. when a set and unset pixel are on top of each other. Since this is not
  2869. always the best use of PUT, you can modify this effect. You can use
  2870. additional statements, called action-verbs after PUT for specific needs.
  2871.  
  2872. The default "action-verb" for PUT is XOR as we demonstrated in the last
  2873. program. Written out the statement would have the following syntax:
  2874.  
  2875.         PUT (x,y),feld,XOR
  2876.  
  2877. You can easily move an objecy, without changing it, across a background and
  2878. create quality animation. The ball in the next program does this:
  2879.  
  2880.         REM 1.6.3.1 Moving Pictures with PUT.
  2881.         DEFINT g
  2882.         COLOR 2,0
  2883.         LOCATE 10,10
  2884.         PRINT "This program moves a ball"
  2885.         LOCATE 11,10
  2886.         PRINT "Around the screen without"
  2887.         LOCATE 12,10
  2888.         PRINT "changing the text!!"
  2889.         DIM g(250)
  2890.         CIRCLE (20,20),20,1,,,.5
  2891.         PAINT (20,20),3,1
  2892.         GET (0,10)-(40,30),g
  2893.         PUT (0,10),g,XOR
  2894.         WHILE INKEY$= ""
  2895.             FOR i = 0 TO 180
  2896.                 PUT(2*i,i),g,XOR
  2897.                 PUT(2*i,i),g,XOR
  2898.             NEXT i
  2899.         WEND
  2900.  
  2901. When you use the PUT statement twice in the same location you get your old
  2902. picture back.
  2903.  
  2904. This simple animation can be compared to the effects created by using
  2905. sprites on a Commodore 64 but these effects are more difficult to create.
  2906. You can achieve many other sprite type effects using different modes of the
  2907. PUT statement.
  2908.  
  2909.                                 PAGE 51
  2910.  
  2911. ----------------------------------------------------------------------------
  2912.  
  2913. The secret of the different modes and the speed of the PUT statement is a
  2914. graphic coprocessor called the Blitter. The blitter can move data around in
  2915. memory with incredible speed.
  2916.  
  2917. Not only does the blitter move data fast, it can also perform operations
  2918. like XOR at the same time.
  2919.  
  2920.                 ------------------------------------------------
  2921.  
  2922. 1.6.3.2 A DIRECT METHOD USING PSET.
  2923.  
  2924. The blitter can also skip any special operations and put the data directly
  2925. on the screen. To achieve this direct, but not necessarily faster method,
  2926. use the PSET mode.
  2927.  
  2928. Remove one of the PUT statements (PUT(2*i,i)g,XOR) in the last program.
  2929. Then replace the XOR in the next PUT line with PSET. Now you can see the
  2930. difference. The graphic, which is drawn over the whole screen, erases
  2931. nothing and draws over anything in its path. We not only have the ball, but
  2932. the entire rectangle that we saved with the GET statement. Even the white
  2933. locations change on the screen using PUT-PSET.
  2934.  
  2935.                 --------------------------------------------------
  2936.  
  2937. 1.6.3.3 INVERTING GRAPHICS.
  2938.  
  2939. Similar to using PSET amd PRESET for setting pixels there is an opposite for
  2940. PUT-PSET called PRESET. By using the PRESET mode you can effortlessly
  2941. invert graphics. You only need two lines for this:
  2942.  
  2943.         GET (X1,Y1)-(X2,Y2),g
  2944.         PUT (X1,Y1),g,PRESET
  2945.  
  2946. The variable g is an integer that you must define before entering these
  2947. lines so that enough memory will be assigned.
  2948.  
  2949. Inverting a graphic means inverting each bit of the graphic. All ones
  2950. become zeros and all zeros become ones. This also causes the colours to
  2951. come from different colour registers. You can calculate the new colour
  2952. register like this:
  2953.  
  2954.         New register = 2^ depth of graphic - old register.
  2955.  
  2956. How the colours change is demonstrated in this next small program.
  2957.  
  2958.                                 PAGE 52
  2959.  
  2960. ----------------------------------------------------------------------------
  2961.  
  2962.         REM 1.6.3.3A Color change with PRESET.
  2963.         DEFINT f
  2964.         DIM f(400)
  2965.         SCREEN 1,320,200,5,1
  2966.         WINDOW 2,,(0,0)-(287,30),16,1
  2967.         FOR i = 1 TO 31
  2968.         LINE (i*9,0)-(i*9+8,40),i,bf
  2969.         NEXT i
  2970.         WHILE INKEY$=""
  2971.         FOR i = 31 TO 0 STEP -1
  2972.             GET (i*9,0)-(i*9+8,40),i,bf
  2973.             PUT (i*9,0),f,PRESET
  2974.         NEXT i
  2975.         WEND
  2976.         WINDOW CLOSE 2
  2977.         SCREEN CLOSE 1
  2978.  
  2979. There are two different ways to restore a picture that you have inverted
  2980. using PUT-PRESET. The first is to invert the same area again.
  2981.  
  2982. We use the method in the following program. A rectangle will wander around
  2983. the screen. Every time it appears we invert the area it is in. Before the
  2984. rectangle moves again we invert the area a second time so that the old the
  2985. rectangle is visible again:
  2986.  
  2987.         REM 1.6.3.3B Invert demo.
  2988.         DEFINT f
  2989.         DIM f(100)
  2990.         CIRCLE (160,80),100,1
  2991.         PAINT STEP (0,0),2,1
  2992.         LINE (120,50)-(150,160),1,b
  2993.         PAINT (121,51),3,1
  2994.         PAINT (179,159),1,1
  2995.         WHILE INKEY$=""
  2996.             FOR i = 1 TO 160           
  2997.                 GET (i,i)-(i+20,i+20),f
  2998.                 PUT (i,i),f,PRESET
  2999.                 FOR t = 0 TO 200:NEXT
  3000.                 GET (i,i)-(i+20,i+20),f
  3001.                 PUT (i,i),f,PRESET
  3002.              NEXT i
  3003.         WEND
  3004.  
  3005. The second method is much shorter and easier. After inverting, draw the
  3006. graphic in the same position again using PUT-PSET.
  3007.  
  3008.                 ---------------------------------------------
  3009.  
  3010. 1.6.3.4 AND or OR
  3011.  
  3012. The logic functions AND and OR are two additional modes for switching with
  3013. PUT. Like XOR, they operate on the individual bits of a pixel, which
  3014. determine its colour instead of the whole pixel.
  3015.  
  3016.  
  3017.                                 PAGE 53
  3018.  
  3019. ----------------------------------------------------------------------------
  3020.  
  3021. If both the screen pixels and the pixel stored with GET are equal to one
  3022. the AND will have a value of one. The following combinations are possible
  3023. with a depth of two and a maximum of four colours :
  3024.  
  3025.         0 AND 0         = 0     
  3026.         0 AND 1         = 0
  3027.         1 AND 0         = 0
  3028.         1 AND 1         = 1
  3029.  
  3030. The following colours result:
  3031.  
  3032. If a pixel is blue (00), the second colour has no effect; it stays blue
  3033. (00). Orange (11) and another colour change the pixel to the other colour. 
  3034. When both colours are the same there is no change. White (01) and black
  3035. (10) changes to blue (00).
  3036.  
  3037. The following is a short program that will demonstrate these combinations.
  3038.  
  3039.         REM 1.6.3.4 AND switch.
  3040.         DEFINT f
  3041.         CIRCLE (160,80),100,1
  3042.         PAINT STEP (0,0),2,1
  3043.         LINE (120,50)-(180,160),1,b
  3044.         PAINT (121,51),3,1
  3045.         PAINT (179,159),1,1
  3046.         PRINT "test"
  3047.         GET (0,0)-(39,8),f
  3048.         FOR i = 20 TO 160 STEP 8
  3049.             PUT (i,i),f,AND
  3050.         NEXT i
  3051. With GET, we store the word "test" as a graphic. Then we PUT this graphic
  3052. in various locations on a four coloured screen. As in the table above, our
  3053. white text is only visible with the orange and white backgrounds.
  3054.  
  3055. When we substitute OR for the AND we achieve an opposite effect. The text
  3056. is visible in the blue and black backgrounds and the blue background of the
  3057. text is not visible at all. The logic table for OR is:
  3058.  
  3059.         0 OR 0  = 0
  3060.         0 OR 1  = 1
  3061.         1 OR 0  = 1
  3062.         1 OR 1  = 1
  3063.  
  3064.                                 PAGE 54
  3065.  
  3066. ----------------------------------------------------------------------------
  3067.                            
  3068. 1.7 ANIMATION IN BASIC
  3069.  
  3070. As an owner of an Amiga, you should be very proud of it's highly praised
  3071. animation cability. You can easily run animations in BASIC by using many
  3072. built-in statements that start with OBJECT.
  3073.  
  3074. To create unusual effects you have to understand how these statements work
  3075. and how to use them. The BASIC handbook lists all of the statements but 
  3076. does not show you everything you can do with them. For example, how to 
  3077. create a bob is left to the included program and the other statement
  3078. explanations are too brief. Some very interesting things like the 
  3079. COLLISION mask, are not even mentioned.
  3080.  
  3081.                 -------------------------------------------------
  3082.  
  3083. 1.7.1 SPRITES AND BOBS.
  3084.  
  3085. The animation statements of BASIC are used for both sprites and bobs and are
  3086. limited to one or the other. Since sprites and bobs could be something new
  3087. to you here is a short definition.
  3088.  
  3089. Both sprites and bobs are moving graphics. Many of us have seen sprites on a
  3090. Commodore 64 and other home computers. On the Amiga, a sprite can be 16 
  3091. pixels wide, as high as the screen and have up to three different colours.
  3092. Sprites can move very quickly and require little programming effort to 
  3093. control.
  3094.  
  3095. Bobs are similar to sprites, but are designed for other uses. A bob can be 
  3096. any size you want and is liited only by the amount of available memory.
  3097. Depending on the depth of the screen, a bob can have up to 32 colours. Bobs
  3098. move slower than sprites and are displayed on the screen using different 
  3099. technology.
  3100.  
  3101. Another difference between bobs and sprites, which we'll discuss later, is a
  3102. set or unset bit in a register. Using more than 4 sprites can get compilcated
  3103. but the number of bobs you can use is limited only by the amount of memory.
  3104.  
  3105.  
  3106.                               PAGE 55
  3107.  
  3108. -----------------------------------------------------------------------------
  3109.  
  3110. 1.7.2 THE OBJECT.SHAPE STATEMENT.
  3111.  
  3112. Unlike with the Commodore 64, you do not have to put the bob and sprite data
  3113. into memory. The OBJECT-SHAPE statement does this for you. After entering all
  3114. the required data using a character string, pass it to the OBJECT-SHAPE 
  3115. statement. This is the only method that you can use in BASIC to define an
  3116. object.
  3117.  
  3118. Because a character string that contains the data for a sprite or bob has a 
  3119. special format, the OBJECT-SHAPE statement will not understand just any
  3120. character string. The following detailed explanation shows you how to define
  3121. your own objects.
  3122.  
  3123.                 --------------------------------------------
  3124.  
  3125. 1.7.3 DESIGNING AN OBJECT.
  3126.  
  3127. There are program included with BASIC, like the OBJEDIT program, that makes
  3128. object editing easy for you. Although OBJEDIT is adequate for most uses, it
  3129. cannot handle self-defined collision masks or shadow pictures (We will 
  3130. explain later what these are and how to use them).
  3131.  
  3132. Why do you have all these fantastic possibilities but lack the software to 
  3133. use them ??. Read on, we can solve this problem.
  3134.  
  3135.                 --------------------------------------------
  3136.  
  3137. 1.7.4 THE COMPLETE OBJECT EDITOR : EDDI II
  3138.  
  3139. Eddi II, which has more options than OBJEDIT, is a program that lets you
  3140. design any type of object. With this program you can create objects with a 
  3141. width of up to 309 pixels and a height of up to 183 pixels. You can also
  3142. change the screen depth, which affects different parameters of the object and
  3143. test your object while in the program. There are so many drawing statements
  3144. that you can use for painting. When you are satisfied with your design, you
  3145. can save it on disk as an object or as a graphic to be loaded with the PUT 
  3146. statement. 
  3147.  
  3148. The program itself is more convincing than anything we can say about it.
  3149. Because of the length of the program you need a minimum of 512K to use it.
  3150.  
  3151.  
  3152.                             PAGE 56
  3153.  
  3154. ----------------------------------------------------------------------------- 
  3155.  
  3156.         REM ***************************************
  3157.         REM 1.7.4 EDDI II
  3158.         REM ***************************************
  3159.         REM 
  3160.         REM
  3161.         REM JENS TRAPP
  3162.         REM
  3163.         CLEAR ,42000 ' Increase work buffer.
  3164.         OPTION BASE 1
  3165.         DEFINT a-r,t-z
  3166.            DEF FNe(b,h,t)=(3*t*h*INT((b+15)/16))
  3167.         REM sprite colours.
  3168.         DIM sr(3), sg(3), sb(3)
  3169.         sr(1)=1 : sg(1)=1 : sb(1)=1        'white
  3170.         sr(2)=0 : sg(2)=0 : sb(2)=0        'black
  3171.         sr(3)=1 : sg(3)=.53 : sb(3)=0      
  3172.         REM Change Menus.
  3173.         MENU 1,0,1,"Window"
  3174.         MENU 1,1,1,"Load"
  3175.         MENU 1,2,1,"Save"
  3176.         MENU 1,3,1,"Size"
  3177.         MENU 1,4,1,"Test"
  3178.         MENU 1,5,1,"Delete"
  3179.         MENU 1,6,1,"Quit"
  3180.         MENU 2,0,1,"Tools"
  3181.         MENU 2,1,2,"  Points 0"
  3182.         MENU 2,2,1,"  Lines"
  3183.         MENU 2,3,1,"  Frames"
  3184.         MENU 2,4,1,"  Boxes"
  3185.         MENU 2,5,1,"  Circles"
  3186.         MENU 2,6,1,"  Fill"
  3187.         MENU 3,0,1,"Depth"
  3188.         MENU 3,1,1," 1  "
  3189.         MENU 3,2,1," 2  "
  3190.         MENU 3,3,1," 3  "
  3191.         MENU 3,4,1," 4  "
  3192.         MENU 3,5,2," 5  "
  3193.         MENU 4,0,1,"Flags"
  3194.         MENU 4,1,1,"  Sprite   "
  3195.         MENU 4,2,1,"  Collision"
  3196.         MENU 4,3,1,"  Shadow   "
  3197.         MENU 4,4,2,"  Saveback "
  3198.         MENU 4,5,2,"  Overlay  "
  3199.         MENU 4,6,1,"  SaveBob  "
  3200.         MENU 4,7,1,"PlanePick  "
  3201.         MENU 4,8,1,"PlaneOnOff "
  3202.         MENU 4,9,0,"SpriteColor"
  3203.         ON MENU GOSUB domenu         'Activate menus.
  3204.         MENU ON
  3205.         MOUSE ON
  3206.         REM default values.
  3207.         sdepth      = 5 ' screen depth
  3208.         gdep        = sdepth ' Depth of graphic.
  3209.         wd          = 100    ' width
  3210.         ht          = 100    ' height
  3211.         thick       = 0      ' brush thickness
  3212.         DIM fd(FNe(wd,ht,gdep))
  3213.  
  3214.  
  3215.                                 PAGE 57
  3216.  
  3217. -----------------------------------------------------------------------------
  3218.  
  3219.         pcolor      = 1 ' Color = white.
  3220.         fcolor      = 1 ' Framecolour = white.        
  3221.         tool        = 1 ' Default toll = "Point"
  3222.         REM flags for standard objects.
  3223.         planepick = 2^gdep-1
  3224.         saveback = 1
  3225.         overlay  = 1
  3226.         REM build screen
  3227.         SCREEN 1,320,200,sdepth,1
  3228.         WINDOW 2,,,16,1
  3229.         GOSUB makescreen
  3230.     Mainloop:
  3231.         a$=INKEY$
  3232.         WHILE a$=""
  3233.             IF MOUSE(0)<>0 THEN GOSUB droutine
  3234.             a$ = INKEY$
  3235.         WEND
  3236.         REM change format.
  3237.         IF ASC(a$)=28 and ht>1 THEN
  3238.             LINE (0,ht+1)-(wd+1,ht+1),8
  3239.             ht = ht - 1
  3240.             fd(2) = ht
  3241.             LINE (0,0)-(wd+1,ht+1),fcolor,b
  3242.         END IF
  3243.         IF ASC(a$)=29 AND ht<184 THEN
  3244.             LINE (1,ht+1)-(wd,ht+1),0
  3245.             ht = ht + 1
  3246.             LINE (0,0)-(wd+1,ht+1),fcolor,b
  3247.         END IF
  3248.         IF fvsprite = 0 THEN
  3249.             IF ASC(a$)=31 AND wd>1 THEN
  3250.                 LINE (wd+1,0)-(wd+1,ht+1),8
  3251.                 wd=wd-1
  3252.                 fd(1)=wd
  3253.                 LINE (0,0)-(wd+1,ht+1),fcolor,b
  3254.             END IF
  3255.             IF ASC(a$)=30 AND wd<WINDOW(2) THEN
  3256.                 LINE (wd+1,1)-(wd+1,ht+1),0
  3257.                 wd = wd + 1
  3258.                 LINE (0,0)-(wd+1,ht+1),fcolor,b
  3259.             END IF
  3260.             IF ASC(a$) = 139 THEN
  3261.                 ERASE fd
  3262.                 DIM fd(FNe(wd,ht,sdepth))
  3263.                 GET (1,1)-(wd,ht),fd
  3264.                 LOCATE 24,1
  3265.                 PRINT "Set the size using the mouse";
  3266.                 WHILE MOUSE(0)=0: WEND
  3267.                 wd=MOUSE(1): IF wd>WINDOW(2) THEN wd=WINDOW(2)
  3268.                 ht=MOUSE(2): IF ht>184 THEN ht=184
  3269.                 GOSUB makescreen
  3270.             END IF
  3271.         END IF
  3272.         IF ASC(a$)>47 AND ASC(a$)<58 THEN thick = ASC(a$)-48: MENU 2,1,1-(tool)=1,"  Points"+STR$(ASC(a$)-48)
  3273.         IF a$<>"q" THEN MainLoop
  3274.  
  3275.  
  3276.                                 PAGE 58
  3277.  
  3278. -----------------------------------------------------------------------------
  3279.   
  3280.     endprog:
  3281.         WINDOW CLOSE 2
  3282.         SCREEN CLOSE 1
  3283.         MENU RESET
  3284.     END
  3285.     makescreen:
  3286.         COLOR 1,0: CLS
  3287.         fd(3)=gdep
  3288.         PUT (1,1),fd,PSET
  3289.     sh2:
  3290.         LINE (0,0)-(wd+1,ht+1),1,b            'Graphic frame.        
  3291.         LINE (wd+2,0)-(WINDOW(2),WINDOW(3)),8,bf
  3292.         LINE (0,ht+2)-(wd+2,WINDOW(3)),8,bf
  3293.         GOTO tf        'Color palette.
  3294.     domenu:
  3295.         title=MENU(0)
  3296.         pnt = MENU(1)
  3297.     ON title GOTO wndow,tools,gdepth,flags1
  3298.     RETURN
  3299.     gdepth:
  3300.         MENU 3,gdep,1
  3301.         planepick=pnt^2
  3302.         IF pnt<gdep THEN
  3303.             ERASE fd
  3304.             DIM fd(FNe(wd,ht,sdepth))
  3305.             GET (1,1)-(wd,ht),fd
  3306.             gdep = pnt
  3307.             GOTO makescreen
  3308.         END IF
  3309.         gdep = pnt
  3310.     tf: MENU 3,gdep,2
  3311.         LINE (0,186)-(WINDOW(2),WINDOW(3)),8,bf
  3312.         FOR i = 0 TO 2^gdep-1
  3313.             LINE (30+i*8,186)-(37+i*8,195),i,bf
  3314.         NEXT i
  3315.         IF pcolor>2^gdep-1 THEN pcolor = 1
  3316.         IF fcolor>2^gdep-1 THEN fcolor = 1
  3317.     GOTO colors2
  3318.     wndow:
  3319.     ON pnt GOTO loader,saver,size,test,del,endprog
  3320.         RETURN
  3321.  
  3322.         tools:
  3323.             MENU 2,tool,1
  3324.             tool = pnt
  3325.             MENU 2,tool,2
  3326.             IF tool=6 THEN
  3327.                 fcolor = pcolor
  3328.                 LINE (0,0)-(wd+1,ht+1),fcolor,b
  3329.                 GOTO colors2
  3330.             END IF
  3331.         RETURN
  3332.  
  3333.         flags1:
  3334.         ON pnt GOTO fvsprite1,coll1,shadmask1,saveback1,overlay1,savebob1,planepick1,planeoff1,sprcolor
  3335.         RETURN
  3336.  
  3337.         fvsprite1:
  3338.         fvsprite = (fvsprite+1)MOD 2
  3339.  
  3340.  
  3341.                                 PAGE 59
  3342.  
  3343. -----------------------------------------------------------------------------
  3344.  
  3345.         fvsprite2:
  3346.             IF fvsprite=1 THEN
  3347.                 MENU 4,1,2
  3348.                 MENU 4,9,1
  3349.                 FOR i = 1 TO 3
  3350.                     PALETTE i,sr(i),sg(i),sb(i)
  3351.                 NEXT i
  3352.                 FOR i = 2 TO 8
  3353.                     MENU 4,i,0
  3354.                 NEXT i
  3355.                 gdep = 2
  3356.                 IF wd<16 THEN
  3357.                     f=0
  3358.                 ELSE
  3359.                     f=8
  3360.                 END IF
  3361.                 LINE (18,0)-(wd+1,ht+1),f,bf
  3362.                 wd=16
  3363.                 LINE (0,0)-(wd+1,ht+1),fcolor,b
  3364.                 FOR i = 1 TO 5
  3365.                     MENU 3,1,0
  3366.                 NEXT i
  3367.                 MENU 3,2,2
  3368.                 collmask = 0
  3369.                 shadmask = 0
  3370.                 saveback = 0
  3371.                 overlay  = 0
  3372.                 savebob  = 0
  3373.                 planeonoff = 0
  3374.             ELSE
  3375.                 MENU 4,9,0
  3376.                 MENU 4,1,1
  3377.                 PALETTE 1,1,1,1
  3378.                 PALETTE 2,0,0,0
  3379.                 PALETTE 3,1,.53,0
  3380.                 FOR i = 2 TO 8
  3381.                     MENU 4,i,1
  3382.                 NEXT i
  3383.                 gdep = 5
  3384.                 MENU 3,0,1
  3385.                 FOR i = 1 TO 4
  3386.                     MENU 3,i,1
  3387.                 NEXT i
  3388.                 MENU 3,5,2
  3389.             END IF
  3390.             planepick = 2^gdep-1
  3391.         GOTO tf
  3392.         
  3393.         coll1:
  3394.             collmask = (collmask+1) MOD 2
  3395.         coll2:
  3396.             IF collmask = 1 THEN
  3397.                 b=0
  3398.                 CALL filename("Collisionmask",coll$,b)
  3399.                 IF coll$ = "" THEN collmask = 0
  3400.             END IF
  3401.             MENU 4,2,1+collmask
  3402.  
  3403.                                 PAGE 60
  3404.  
  3405. -----------------------------------------------------------------------------
  3406.  
  3407.         RETURN
  3408.         shadmask1:
  3409.             shadmask = (shadmask + 1) MOD 2
  3410.         shad2:
  3411.             IF shadmask = 1 THEN
  3412.                 b=0
  3413.                 CALL filename("ShadowMask",shad$,b)
  3414.                 IF shad$ = "" THEN shadmask = 0
  3415.             END IF
  3416.             MENU 4,3,1+shadmask
  3417.         RETURN
  3418.  
  3419.         saveback1:
  3420.             saveback = (saveback+1) MOD 2
  3421.             MENU 4,4,1+saveback
  3422.         RETURN
  3423.  
  3424.         overlay1:
  3425.             overlay = (overlay+1) MOD 2
  3426.             MENU 4,5,1+overlay
  3427.         RETURN
  3428.  
  3429.         savebob1:
  3430.             savebob = (savebob+1) MOD 2
  3431.             MENU 4,6,1+savebob
  3432.         RETURN
  3433.         
  3434.         planepick1:
  3435.             CALL planes("PlanePick",planepick)
  3436.         RETURN
  3437.  
  3438.         planeonoff1:
  3439.             CALL planes("Planeonoff",planeonoff)
  3440.         RETURN
  3441.  
  3442.         sprcolor:
  3443.             WINDOW 3,"Sprite Color",(0,0)-(200,40),16,1
  3444.             INPUT "Color 1,2 or 3";a
  3445.             IF a>0 AND a<4 THEN
  3446.                 INPUT "Red range : ";sr(a)
  3447.                 INPUT "Green range:";sg(a)
  3448.                 INPUT "Blue range :";sb(A)
  3449.                 PALETTE a,sr(a),sg(a),sb(a)
  3450.             END IF
  3451.             WINDOW CLOSE 3
  3452.             RETURN
  3453.  
  3454.         droutine:
  3455.             x = MOUSE(1)
  3456.             y = MOUSE(2)
  3457.             xalt = MOUSE(3)
  3458.             yalt = MOUSE(4)
  3459.             IF y>185 THEN colors
  3460.             IF x>wd OR x<1 OR y>ht OR y<1 THEN RETURN
  3461.             ON tool GOTO pnte,w,w,w,w,fillroutine
  3462.         w:
  3463.             IF MOUSE(0) <> 0 THEN
  3464.                 f1=POINT(xalt,yalt)
  3465.                 PSET(xalt,yalt),-(f1=0)
  3466.                 f2=POINT(x,y)
  3467.                 PSET(x,y),-(f2=0)
  3468.                 PSET(x,y),f2
  3469.                 PSET(xalt,yalt),f1
  3470.             ELSE
  3471.  
  3472.                                 PAGE 61
  3473.  
  3474. -----------------------------------------------------------------------------
  3475.  
  3476.             ON tool GOTO droutine,linetool,frametool,boxtool,circletool
  3477.         END IF
  3478.         GOTO droutine
  3479.  
  3480.         del:
  3481.          LINE(1,1)-(wd,ht),0,bf
  3482.         RETURN
  3483.  
  3484.         pnte:
  3485.            x1=x+thick: IF x1>wd THEN x1=wd
  3486.            y1=y+thick: IF y1>ht THEN y1=ht
  3487.            LINE (x,y)-(x1,y1),pcolor,bf
  3488.         RETURN
  3489.  
  3490.         linetool:
  3491.            LINE(x,y)-(xalt,yalt),pcolor
  3492.         RETURN
  3493.  
  3494.         frametool:
  3495.            LINE (x,y)-(xalt,yalt),pcolor,b
  3496.         RETURN
  3497.         
  3498.         boxtool:
  3499.             LINE (x,y)-(xalt,yalt),pcolor,bf
  3500.         RETURN
  3501.  
  3502.         circletool:
  3503.             IF y<>yalt AND x<>xalt THEN
  3504.                 r=ABS(x-xalt):v=ABS(y-yalt)
  3505.                 IF v<r THEN
  3506.                     CIRCLE(xalt,yalt),r,pcolor,,,v/r
  3507.                 ELSE
  3508.                     CIRCLE(xalt,yalt),v,pcolor,,,v/r
  3509.                 END IF
  3510.             END IF
  3511.         GOTO sh2
  3512.  
  3513.         fillroutine:
  3514.             PAINT(x,y),pcolor,fcolor
  3515.         RETURN
  3516.  
  3517.         colors:
  3518.             IF POINT(x,y)>=0 THEN pcolor=POINT(x,y)
  3519.  
  3520.         colors2:
  3521.             LINE (0,186)-(25,195),pcolor,bf
  3522.             LINE (0,186)-(25,195),fcolor,b
  3523.         RETURN
  3524.  
  3525.         size:
  3526.             WINDOW 3,"Size",(0,0)-(200,30),16,1
  3527.             PRINT "Width  = ";wd
  3528.             PRINT "Height = ";ht
  3529.             PRINT "Press any key";
  3530.             WHILE INKEY$="": WEND
  3531.             WINDOW CLOSE 3
  3532.         RETURN
  3533.  
  3534.         test:
  3535.             ERASE fd
  3536.             DIM fd(FNe(wd,ht,sdepth))
  3537.             GET (1,1)-(wd,ht),fd
  3538.             CLS
  3539.             LOCATE 10,5
  3540.             PRINT "Working"
  3541.             GOSUB BFormat
  3542.  
  3543.                                 PAGE 62
  3544.  
  3545. -----------------------------------------------------------------------------
  3546.   
  3547.         OBJECT SHAPE 1,a$
  3548.         ON COLLISION GOSUB initobj
  3549.         COLLISION ON
  3550.         GOSUB initobj
  3551.         OBJECT ON
  3552.         FOR i = 0 TO 100
  3553.             COLOR INT(RND*32)
  3554.             LOCATE INT(RND*22)+1,RND*50+1
  3555.             PRINT "EDDI II"
  3556.         NEXT i
  3557.         WHILE INKEY$ = "": WEND
  3558.         OBJECT.OFF
  3559.         OBJECT.STOP
  3560.         COLLISION OFF
  3561.     GOTO makescreen
  3562.     initobj:
  3563.         OBJECT.X 1,10
  3564.         OBJECT.Y 1,10
  3565.         OBJECT.VX 1,20
  3566.         OBJECT.VY 1,15
  3567.         OBJECT.START 1
  3568.     RETURN
  3569.  
  3570.          loader:
  3571.           b = 1
  3572.           MENU 3,gdep,1
  3573.           CALL filename("Load",n$,b)
  3574.           IF n$ = "" OR b=2 THEN RETURN
  3575.           OPEN n$ FOR INPUT AS #1
  3576.           IF b=0 THEN
  3577.              INPUT #1,wd,ht,gdep
  3578.              ERASE fd
  3579.              DIM fd(FNe(wd,ht,sdepth))
  3580.              FOR i = 4 TO FNe(wd,ht,sdepth))
  3581.                  INPUT #1,fd(i)
  3582.              NEXT i
  3583.              fd(1) = wd
  3584.              fd(2) = ht
  3585.              fd(3) = gdep
  3586.              planepick = 2^gdep-1
  3587.           ELSE
  3588.              ColorSet = CVL(INPUT$(4,1)) ' These variables are not
  3589.              DataSet  = CVL(INPUT$(4,1)) ' used by this program.
  3590.              gdep     = CVL(INPUT$(4,1)) 
  3591.              wd       = CVL(INPUT$(4,1))
  3592.              ht       = CVL(INPUT$(4,1))
  3593.              flags    = CVI(INPUT$(2,1))
  3594.              planepick= CVI(INPUT$(2,1))
  3595.              planeonoff = CVI(INPUT$(2,1))
  3596.              ERASE fd
  3597.              DIM fd(FNe(wd,ht,gdep))
  3598.              fd(1) = wd
  3599.              fd(2) = ht
  3600.              fd(3) = gdep
  3601.              FOR i = 4 TO FNe(wd,ht,gdep)
  3602.                 fd(i)=CVI(INPUT$(2,1))
  3603.  
  3604.                                 PAGE 63
  3605.  
  3606. -----------------------------------------------------------------------------
  3607.  
  3608.              NEXT i
  3609.          END IF
  3610.         IF flags AND 1 THEN
  3611.             fvsprite = 1
  3612.             FOR i = 1 TO 31
  3613.                 a=CVI(INPUT$(2,1))
  3614.                 sr(i)=(a AND 3840)/3840
  3615.                 sg(i)=(a AND 240)/240
  3616.                 sb(i)=(a AND 15)/15
  3617.             NEXT i
  3618.             GOSUB fvsprite2
  3619.         ELSE
  3620.             collmask=(flags AND 2)/2
  3621.             shadmask=(flags AND 4)/4
  3622.             saveback=(flags AND 8)/8
  3623.             overlay =(flags AND 16)/16
  3624.             savebob =(flags AND 32)/32
  3625.             MENU 4,1,1
  3626.             MENU 4,2,1+collmask
  3627.             MENU 4,3,1+shadmask
  3628.             MENU 4,4,1+saveback
  3629.             MENU 4,5,1+overlay
  3630.             MENU 4,6,1+savebob
  3631.             IF shadmask = 1 THEN
  3632.                 b=0:shad$=""
  3633.                 CALL filename("Shadowmask",shad$,b)
  3634.                 IF shad$<>"" THEN
  3635.                     OPEN shad$ FOR OUTPUT AS 2
  3636.                         PRINT #2,wd;ht;1;
  3637.                 END IF
  3638.                 FOR i = 4 TO FNe(wd,ht,1)
  3639.                     a = CVI(INPUT$(2,1))
  3640.                         IF shad$<>"" THEN PRINT #2,a;
  3641.                 NEXT i
  3642.                 IF shad$<>"" THEN CLOSE 2
  3643.             END IF
  3644.             IF collmask = 1 THEN 
  3645.                 b = 0: coll$ = ""
  3646.                 CALL filename("CollisionMask",shad$,b)
  3647.                 IF coll$<>"" THEN
  3648.                     OPEN coll$ FOR OUTPUT AS 2
  3649.                     PRINT #2,wd;ht;1;
  3650.                     FOR i = 4 TO FNe(wd,ht,1)
  3651.                         PRINT #2,CVI(INPUT$(2,1));
  3652.                     NEXT i
  3653.                     CLOSE 2
  3654.                 END IF
  3655.             END IF
  3656.         END IF
  3657.         CLOSE 1
  3658.         
  3659.     GOTO makescreen
  3660.         saver:
  3661.         b=1
  3662.         ERASE fd
  3663.         DIM fd(FNe(wd,ht,sdepth))
  3664.         GET (1,1)-(wd,ht),fd
  3665.  
  3666.                                 PAGE 64
  3667.  
  3668. -----------------------------------------------------------------------------
  3669.  
  3670.         CALL filename("Save",n$,b)
  3671.         IF n$="" OR b=2 THEN RETURN
  3672.         OPEN n$ FOR OUTPUT AS 2
  3673.             IF b=1 THEN
  3674.                 GOSUB BFormat
  3675.                 PRINT #2,a$;
  3676.             ELSE
  3677.                 PRINT #2,wd,ht,gdep
  3678.                 FOR i = 4 TO FNe(wd,ht,gdep)
  3679.                     PRINT #2,fd(i)
  3680.                 NEXT i
  3681.             END IF
  3682.             CLOSE 2
  3683.         RETURN
  3684.  
  3685.         BFormat:
  3686.             a$=MKL$(0)+MKL$(0)
  3687.             a$=a$+MKI$(0)+MKI$(gdep)
  3688.             a$=a$+MKI$(0)+MKI$(wd)
  3689.             a$=a$+MKI$(0)+MKI$(ht)
  3690.             flags = fvsprite+2*vcollmask+4*shadmask+8*saveback
  3691.             flags = flags + 16*overlay + 32*savebob
  3692.             a$ = a$+MKI$(flags)
  3693.             a$ = a$+MKI$(planepick)
  3694.             a$ = a$+MKI$(planeonoff)
  3695.             FOR i = 4 TO FNe(wd,ht,gdep)
  3696.                 a$=a$ + MKI$(fd(i))
  3697.             NEXT i
  3698.             IF shadmask THEN
  3699.                 IF shad$ = "" THEN GOSUB shad2
  3700.                 OPEN shad$ FOR INPUT AS 1
  3701.                 INPUT #1,b,h,t
  3702.                 IF b<>wd or h<>ht THEN
  3703.                     LOCATE 10,4
  3704.                     PRINT "Not in ShadowMask format!"
  3705.                     CLOSE 1
  3706.                     WHILE INKEY$ = "": WEND
  3707.                     GOTO makescreen
  3708.                 END IF
  3709.                 FOR i = 4 TO FNe(wd,ht,1)
  3710.                     INPUT #1,a
  3711.                     a$=a$+MKI$(a)
  3712.                 NEXT i
  3713.                 CLOSE 1
  3714.             END IF
  3715.             IF collmask THEN
  3716.                 IF coll$="" THEN coll2
  3717.                 OPEN coll$ FOR INPUT AS 1
  3718.                 INPUT 1,b,h,t
  3719.                 IF b<>wd OR h<>ht THEN
  3720.                     LOCATE 10,4
  3721.                     PRINT "Not in collision mask format!"
  3722.                     CLOSE 1
  3723.                     WHILE INKEY$="": WEND
  3724.                     GOTO makescreen
  3725.                 END IF
  3726.                 FOR i = 4 TO FNe(wd,ht,1)
  3727.  
  3728.                                 PAGE 65
  3729.  
  3730. -----------------------------------------------------------------------------
  3731.  
  3732.                     INPUT #1,a$
  3733.                 a$ = a$+MKI$(a)
  3734.             NEXT i
  3735.             CLOSE i
  3736.         END IF
  3737.         IF fvsprite THEN
  3738.             a$=a$+MKI$(INT(sr(1)*15)*256+INT(sg(1)*15)*16+sb(1)*15) 'sprcolor1
  3739.             a$=a$+MKI$(INT(sr(2)*15)*256+INT(sg(2)*15)*16+sb(2)*15) 'sprcol2
  3740.             a$=a$+MKI$(INT(sr(3)*15)*256+INT(sg(3)*15)*16+sb(3)*15) 'sprcolor3
  3741.         END IF
  3742.         RETURN
  3743.  
  3744.         SUB planes(b$,p) STATIC
  3745.             WINDOW 3,b$,(0,0)-(150,24),16,1
  3746.             PRINT "End with <RETURN>"
  3747.         p1: FOR i = 0 TO 4
  3748.                 LOCATE 2,2+i*2
  3749.                 PRINT i;
  3750.                 LOCATE 3,2+i*2
  3751.                 PRINT (2^i AND p)/2^1 ;
  3752.             NEXT i
  3753.             a$=""
  3754.             WHILE a$=""
  3755.                 a$=INKEY$
  3756.             WEND
  3757.             IF ASC(a$)>=48 AND ASC(a$)<53 THEN p = p XOR 2^(ASC(a$)-48)
  3758.             IF ASC(a$)<>13 THEN p1
  3759.             WINDOW CLOSE 3
  3760.         END SUB
  3761.  
  3762.         SUB filename(b$,c$,d) STATIC
  3763.             WINDOW 3,b$,(0,0)-(300,40),16,1
  3764.             IF c$<>"" THEN
  3765.                 PRINT "Old "b$"Filename :"
  3766.                 PRINT c$
  3767.                 PRINT "<return> for same name"
  3768.             END IF
  3769.             INPUT "New Filename :",d$
  3770.             IF d$<>"" THEN c$=d$
  3771.             IF d=1 THEN 
  3772.                 PRINT "Bob or Put Format"
  3773.                 INPUT "(b/p)";d$
  3774.                 IF d$="b" THEN
  3775.                     d=1
  3776.                 ELSE
  3777.                     IF d$="p" THEN
  3778.                         d=0
  3779.                     ELSE
  3780.                         d=2
  3781.                     END IF
  3782.                 END IF
  3783.             END IF
  3784.             WINDOW CLOSE 3
  3785.         END SUB
  3786.  
  3787.                                 PAGE 66
  3788.  
  3789. -----------------------------------------------------------------------------
  3790.  
  3791. The most important variables:
  3792.  
  3793. fd       : Short integer array. This field stores the screen information and
  3794.            is easily used with PUT and GET to display the graphic. fd(1) is 
  3795.            the width , fd(2) the height and fd(3) the depth. This size of 
  3796.            the array is self-defining using a function.
  3797.  
  3798. wd       : Width of the graphic. Since our graphic always starts with 1,1
  3799.            we can increase to the maximum whilst drawing.
  3800.  
  3801. ht       : Height and last Y value of the graphic.
  3802.  
  3803. depth    : Actual depth of the graphic. This value has no effect on the 
  3804.            screen depth.
  3805.  
  3806. sdepth   : Actual depth of the screen. This value stays the same.
  3807.  
  3808. x        : X coordinate when drawing.
  3809.  
  3810. y        : Y coordinate when drawing.
  3811.  
  3812. xalt     : Starting coordinate for drawing lines etc.
  3813.  
  3814. yalt     : Y coordinate. Identical use as xalt.
  3815.  
  3816. pcolor   : Actual drawing color.
  3817. fcolor   : Color of the frame when filling. The fill function uses the 
  3818.            frame colour.
  3819.  
  3820. tool     : The number of the actual drawing statement.
  3821.  
  3822. title    : Number of the active menu.
  3823.  
  3824. pnt      : Numbe of the active submenu.
  3825.  
  3826. b        : Help variable for format decisions.
  3827.  
  3828. thick    : Brush width for "Point"
  3829.  
  3830. n$       : Data name for loading and saving.
  3831.  
  3832. coll$    : Data name for the collision mask (See Below)
  3833.  
  3834. Shad$    : Data name for the shadowmask (See Below)
  3835.  
  3836. All object variables and flags will be explained in the following sections.
  3837.  
  3838.                                 PAGE 67
  3839.  
  3840. -----------------------------------------------------------------------------
  3841.  
  3842. 1.7.4.1 THE SCREEN
  3843.  
  3844. When you start the program your design board will appear on the screen 
  3845. (Eddi's own window and screen). In this window you will see two things:
  3846.  
  3847. 1.) all 32 colors in small boxes at the bottom of the screen and
  3848. 2.) a large window frames in white. This window is where you can design 
  3849.     all your objects.
  3850.  
  3851.                 ---------------------------------------------
  3852.  
  3853. 1.7.4.2 OBJECT SIZE
  3854.  
  3855. The first thing you should do is set the size of the object. You can change
  3856. this size later, but you should have an idea of the form and size you want 
  3857. before you start.
  3858.  
  3859. To find out the current size of your object, activate the menu item SIZE in
  3860. the WINDOW menu, which displays the width and height. You can change these
  3861. values in two different ways by using the keyboard.
  3862.  
  3863. 1.) The cursor keys. The size of the object is increased or decreased.
  3864. 2.) First press the help key and then use the mouse pointer to indicate the
  3865.     new lower right hand corner of the object.
  3866.  
  3867. The top left hand corner of the object is always in the top left hand corner
  3868. of the screen and cannot be changed. You can shrink both height and width 
  3869. all the way down to one. You can even define an object as small as one pixel.
  3870. This is the smallest possible object.
  3871.  
  3872. The maximum size of 312*184, if you have enough memory, is large enough for
  3873. most uses.
  3874.  
  3875.                                 PAGE 68
  3876.  
  3877. -----------------------------------------------------------------------------
  3878.  
  3879. 1.7.4.3 DEPTH
  3880.  
  3881. Depth is also important to the format of your object because it determines
  3882. the maximum number of colours the object can have. For example, with a 
  3883. depth of five you can have up to 32 colours. Depth is processed in a special
  3884. way in this program and has its own menu that allows you to check or change
  3885. the current depth.
  3886.  
  3887. A checkmark in the depth menu indicates the actual depth. You can change this
  3888. the same way you select items in the workbench menus.
  3889.  
  3890. When you change the depth, the number of available colours and the length of 
  3891. the colour bar also changes. Any full colour object that you currently have
  3892. in the design window is also affected.
  3893.  
  3894.                 ----------------------------------------
  3895.  
  3896. 1.7.4.4 COLORS
  3897.  
  3898. Look closely at the row of available colors and you can see that the first
  3899. square is slightly larger than the rest. This square indicates the current 
  3900. drawing color. To select a different drawing color just click with the
  3901. mouse button on the color you want.
  3902.  
  3903.                 -------------------------------------------
  3904.  
  3905. 1.7.4.5 DRAWING
  3906.  
  3907. Finally we have reached the main part of the program: Drawing. There are six
  3908. drawing modes located in the "tools" menu. This menu contains just about 
  3909. everything you will need to draw wonderful pictures. To find the graphic 
  3910. statements we have already discussed, look through the program listing.
  3911. All of the following statements use the current selected colour:
  3912.  
  3913. Points N POINT is a drawing statement you learned in some of the 
  3914.          demonstrations. When you click the left mouse button you will set
  3915.          a pixel where the mouse pointer is located. This statement also 
  3916.          performs a special function. Instead of just setting pixels you 
  3917.          can set blocks of pixels 9*9 in size. The number after "point" 
  3918.          determines the brush size and can be changed from the keyboard 
  3919.          using the number keys (0-9).
  3920.  
  3921.                                 PAGE 69
  3922.  
  3923. -----------------------------------------------------------------------------
  3924.  
  3925. LINES    : The menu item works exactly like the Basic LINE statement. You 
  3926.            click and hold the left mouse button wherever you want to start
  3927.            a line, then move to where you want the line to end and release 
  3928.            the button. Whil you hold the button, the start and end points 
  3929.            of the line will blink. This allows you to easily determine the 
  3930.            direction and level of the line.
  3931.  
  3932. FRAMES   : This statement draws an unfilled rectangle. You set the upper 
  3933.            left and lower right hand corners in the same way you set the
  3934.            ends of the line above.
  3935.  
  3936. BOXES    : Boxes performs the opposite of frames by drawing a filled 
  3937.            rectangle. You accomplish the sizing the same way.
  3938.  
  3939. CIRCLES  : The circle menu item lets you set your parameters using the mouse
  3940.            which is much easier than the BASIC method. Sizing is similar to
  3941.            the line statement, but with circle, your start point will be the
  3942.            centre of the circle. The points where you release the mouse 
  3943.            button sets the maximum height and width of the circle. However,
  3944.            this release point is never part of the circle. The X and Y 
  3945.            difference in relation to the release point determines the 
  3946.            horizontal and vertical radius. Therefore, the two points you 
  3947.            set with the mouse mark exactly a quarter of the circle.
  3948.  
  3949. FILL     : The lasst object fills any framed area. Unlike OBJEDIT , this 
  3950.            fill statement allows you to fill an area with a different color
  3951.            than the frame of the area. When you select fill the program
  3952.            automatically selects the drawing colour as the frame and fill 
  3953.            colour. If you select a different colour while "fill" is active,
  3954.            the frame colour does not change. The program indicates the 
  3955.            current colour by a frame around the drawing colour and around
  3956.            the object.
  3957.  
  3958. Use the DELETE option from the WINDOW menu to clear the screen when you are
  3959. not satisfied with an object design.
  3960.  
  3961.                                 PAGE 70
  3962.  
  3963. -----------------------------------------------------------------------------
  3964.  
  3965. 1.7.4.6 LOADING AND SAVING.
  3966.  
  3967. In order to keep your masterpiece you need load and save options. The BASIC 
  3968. statements GET and PUT are perfect for this.
  3969.  
  3970. Actually, you can save and load your data in two different formats. The 
  3971. first format uses the PUT statement to save data in short integer form.
  3972. As you saw in previous demonstrations, the data is easily loaded using the
  3973. PUT and GET statements and is displayed in original form on your screen.
  3974.  
  3975. The second format is designed for bobs and is used to create files for bobs
  3976. and sprites. Besides the raw picture information, these files contain many
  3977. other values for objects and are displayed using the OBJECT.SHAPE 
  3978. statement.
  3979.  
  3980. The program remembers the last filename used for a load or save. To load
  3981. or save using the same filename you only have to press the <Return> key.
  3982.  
  3983.                 -----------------------------------------
  3984.  
  3985. 1.7.4.7 TESTING OBJECTS.
  3986.  
  3987. The TEST option in the WINDOW menu enables you to test your new objects
  3988. without having to exit the editor. You can make quick changes easily if
  3989. the object is not exactly what you want.
  3990.  
  3991. You do not have to save an object to disk before testing it. We take the 
  3992. data directly from the screen and convert it to the OBJECT.SHAPE statement
  3993. format. Therefore, you can test it out before you save it. To exit the test
  3994. mode press any key.
  3995.  
  3996.                 -------------------------------------------------
  3997.  
  3998. 1.7.4.8 EXITING EDDI II.
  3999.  
  4000. Even when exiting the program has two options. You can select QUIT from the
  4001. window menu, or simply press the <q> key. Remember that exiting the program
  4002. clears all data so be sure you have saved your object first.
  4003.  
  4004.  
  4005.                                 PAGE 71
  4006.  
  4007. -----------------------------------------------------------------------------
  4008.  
  4009. Upon exiting, the window and screen for the program are closed and the 
  4010. normal BASIC menus are activated again.
  4011.  
  4012.                 --------------------------------------------
  4013.  
  4014. 1.7.4.9 LOADING OBJECTS INTO YOUR PROGRAMS.
  4015.  
  4016. To load the objects as bobs you must save them in bob format. Then it is 
  4017. quite easy to load them again using the OBJECT.SHAPE statement.
  4018.  
  4019.          OPEN "filename" FOR INPUT as 1
  4020.          OBJECT.SHAPE 1,INPUT$(LOF(1),1)
  4021.          CLOSE 1
  4022.  
  4023.                 --------------------------------------------
  4024.  
  4025. 1.7.5 FLAGS.
  4026.  
  4027. The flags determine the appearance of an object on the screen. Each flag 
  4028. has two possible settings. It is either set and equals 1 or not set and 
  4029. equals zero. Several flags are combined into one byte and all flags are
  4030. passed to the computer in the character string that is used with the 
  4031. OBJECT.SHAPE statement. Once set, flags cannot be modified from BASIC.
  4032.  
  4033. Our editor has it's own menu for the flags. Set flags are indicated by a 
  4034. small check in the menu.
  4035.  
  4036. There are two other functions in the FLAG menu besides the flags:  
  4037. PLANEPICK and PLANEONOFF. We will explain a bit later what these two do.
  4038.  
  4039.                 --------------------------------------------
  4040.  
  4041. 1.7.5.1 THE SAVEBACK FLAG.
  4042.  
  4043. We will discuss the SaveBack flag first because it is the simplest one. All
  4044. flags have names that help you remember what they do. For example, SaveBack
  4045. is an abbreviation for "save the background".
  4046.  
  4047. When you draw a bob it becomes part of the existing screen. What was on the 
  4048. screen is painted over. To save and restore what the bob covers when it is
  4049. moved, you have to set the SaveBack flag.
  4050.  
  4051.                                 PAGE 72
  4052.  
  4053. -----------------------------------------------------------------------------
  4054.  
  4055. When the SaveBack flag is not set and you move the object, the original 
  4056. object image will still be on the screen. Test this out with one of your
  4057. objects in the editor. 
  4058.  
  4059. When this flag is set and you are moving large objects, there will be a
  4060. flickering on the screen. Also, screens with a lot of depth will have the 
  4061. same effect. Since there is no way to counter this flicker while using 
  4062. BASIC, you should set this flag only if you really need it. 
  4063.  
  4064. At this point we need another sample program. To keep our program short,
  4065. we have used smaller objects. The number of data statements required for
  4066. biger objects would make this demonstration program too large.
  4067.  
  4068.  
  4069.         REM 1.7.5.1 Airplane.
  4070.         DEFINT a
  4071.         SCREEN 1,320,200,2,1
  4072.         WINDOW 2,,,16,1
  4073.         PRINT "Reading in DATA ......."
  4074.         FOR i = 1 TO 313
  4075.             READ a
  4076.             a$ = a$+MKI$(a)
  4077.         NEXT i
  4078.         LOCATE 10,1
  4079.         PRINT "In this Object demo you will see an"
  4080.         PRINT "airplane that flies accross the"
  4081.         PRINT "screen, without having any effect"
  4082.         PRINT "on this text."
  4083.         OBJECT.SHAPE ,a$
  4084.         OBJECT.SHAPE 1,a$
  4085.         ShowOBJ:
  4086.         OBJECT.X 1,1
  4087.         OBJECT.Y 1,80
  4088.         OBJECT.VX 1,3
  4089.         OBJECT.VY 1,20
  4090.         OBJECT.AX 1,4
  4091.         OBJECT.AY 1,-2
  4092.         OBJECT.ON
  4093.         OBJECT.START
  4094.         WHILE INKEY$ = "":WEND
  4095.         GOTO ShowOBJ
  4096.          
  4097.         REM Data for the airplane.
  4098.         DATA 0,0,0,0,0,2,0,88,0,25
  4099.         DATA 8: REM This is the value for thew flags.
  4100.         DATA 3,0,8160,0,0,0,0,0,16368,0,0,0,0
  4101.         DATA 0,16376,0,0,0,0,0,16380,0,0,896,0
  4102.         DATA 0,16382,0,0,-1,-32768&,0,16382,0,1,-28668,-16384
  4103.         DATA 0,16383,0,3,4100,24576,0,16383,0,6,4100,12288
  4104.         DATA 0,16383,-32768,12,4100,6144,0,16383,-16384,24,4100,3072
  4105.         DATA 0,16383,-16384,48,4100,2044,0,16383,-2048,127,-1,-1
  4106.         DATA 0,16383,-1,-1,-1,-14337,0,16383,-1,-1,-2048,12543
  4107.         DATA 0,16383,-1,-4,-1023,-385,0,4095,-1,-31,-1,-129
  4108.         DATA -32768,4095,-1,-497,-1,-129,-32768,1023,-1,-257,-1,-129
  4109.  
  4110.                                 PAGE 73
  4111.  
  4112. -----------------------------------------------------------------------------
  4113.  
  4114.         DATA -32768,1023,-1,-257,-1,-129,-32768,1023,-1,-129,-1,-385
  4115.         DATA -32768,511,-1,-249,-1,-257,0,7,-1,-32,0,504
  4116.         DATA 0,0,0,16383,-1,-32,0,0,0,0,2044,0
  4117.         DATA 0,0,0,0,0,0,0,0,0,0,0,0
  4118.         DATA 0,0,0,0,0,0,0,0,0,0,0,0
  4119.         DATA 0,0,0,0,0,0,0,8176,0,0,0,0
  4120.         DATA 0,1536,0,0,28667,0,1024,1648,0,0,-4101,-32768
  4121.         DATA 1024,1736,0,0,-4101,-32768,1024,1728,0,0,28667,8192
  4122.         DATA 1024,1728,0,0,28667,-32768,1024,1728,0,0,28667,-32768
  4123.         DATA 1024,1728,0,0,0,0,1024,1736,0,0,0,0
  4124.         DATA 2048,1648,0,0,0,0,2048,0,0,0,0,0
  4125.         DATA 14336,0,0,0,0,127,-2048,0,0,0,0,127
  4126.         DATA -2048,3,-1,-512,0,0,26624,1023,-1,-512,0,0
  4127.         DATA 2048,0,0,256,0,0,3072,0,0,0,0,0
  4128.         DATA 1024,0,0,0,0,0,1024,0,0,0,0,0
  4129.         DATA 1024,0,0,0,0,0,1024,0,0,0,0,0,1024
  4130.  
  4131. We have included the OBJECT statements in this program. You have to use most
  4132. of these statements for any object. Here are the individual explanations:
  4133.  
  4134. OBJECT.SHAPE : The character string a$ contains all the necessary 
  4135.                information you have to pass to the computer. When you want
  4136.                to use an object you must specify the number assigned to it
  4137.                with OBJECT.SHAPE. In our program that number was 1.
  4138.                Previously we demonstrated how you load the object data from
  4139.                disk.
  4140.  
  4141. OBJECT.X/Y     With these statements you set the start position.
  4142.                The first parameters sets the object numbers.
  4143.  
  4144. OBJECT.VX/Y    This statement sets the speed (velocity) for the selected
  4145.                object.
  4146.  
  4147. OBJECT.AX/Y    The velocity of an object does not have to be constant.
  4148.                You can set an acceleration factor with this statement.
  4149.  
  4150. OBJECT.ON      Makes the specified object visible on the screen.
  4151.  
  4152. OBJECT.START   Even though you have set a velocity and acceleration for your
  4153.                object, it will not move until you execute this statement.
  4154.  
  4155. This program is a very good demonstration of the SaveBack flag. The text 
  4156. remains visible even though the airplane flies right over the text.
  4157.  
  4158.                                 PAGE 74
  4159.  
  4160. -----------------------------------------------------------------------------
  4161.  
  4162. If you want to see what happens when the SaveBack flag is not set, change 
  4163. the 11th value (the only value in the second DATA line) in the data list.
  4164. Change the eight to zero> Now when you run the program one corner of the
  4165. airplane will leave a trail on the screen.
  4166.  
  4167.                 --------------------------------------------
  4168.  
  4169. 1.7.5.2 SAVEBOB.
  4170.  
  4171. The SAVEBOB flag is almost the opposite of SaveBack flag. When you set 
  4172. SaveBob, the object remains on the screen. You might be familiar with this 
  4173. effect from some of the better paint programs. This method allows you to 
  4174. draw while an object is on the screen.
  4175.  
  4176.                 --------------------------------------------
  4177.  
  4178. 1.7.5.3 OVERLAY.
  4179.  
  4180. In our last sample program you probably noticed that when the airplane
  4181. flew over the text it covered a much larger size than the actual area of the
  4182. airplane. This effect can be removed with the overlay flag. When the overlay
  4183. flag is set, all the unset pixels of the object become transparent. You can
  4184. then see the background through the object wherever there are no set pixels.
  4185. To test this out on our airplane, set the overlay flag by adding 16 to the
  4186. eight of the SaveBack flag. The new flag becomes 24 and both flags are
  4187. active.
  4188.  
  4189. This is only one of many possibilities you have with Overlay. The other uses
  4190. are connected to the shadow mask.
  4191.  
  4192.                 --------------------------------------------
  4193.  
  4194. 1.7.5.4 THE SHADOW MASK.
  4195.  
  4196. The SHADOW mask is one of two masks that you can define for each object. 
  4197. With the SHADOW mask you can specify which pixels the background covers and
  4198. which pixels only change the colour of the background. Also, if you have
  4199. set the Overlay flag, the Shadowmask determined which pixels of the object
  4200. are visible.
  4201.  
  4202. The mask must have the same width and heightas the object you use with it.
  4203. In format, a mask and object are the same, except the mask depth is 
  4204. independant of the object depth. Each bit in the mask is equal to one pixel
  4205. of the object. If a bit in the mask is set, the corresponding pixel in the 
  4206. object is on top of the background.
  4207.  
  4208.                                 PAGE 75
  4209.  
  4210. -----------------------------------------------------------------------------
  4211.  
  4212. The Overlay flag handles unset pixels. If the overlay flag is set, the 
  4213. object pixel has no effect on the background. If the overlay flag is unset,
  4214. the colour of the background pixel is changed.
  4215.  
  4216. If the OVerlay flag is set the computer will create a default shadow mask
  4217. (if you have not created one). In this mask, all bits are set to match the
  4218. set pixels of the object. This makes all the unset pixels of the object 
  4219. transparent.
  4220.  
  4221. When you want to create your own SHADOW mask with the editor you should use
  4222. the following steps:
  4223.  
  4224. 1. First you must already have an object for the mask. The best way to do 
  4225.    this is to load your object first which gives you the correct format for
  4226.    the mask.
  4227.  
  4228. 2. Set the depth to one.
  4229.  
  4230. 3. Draw the mask. Any remaining pixels from the object can assist you with
  4231.    this.
  4232.  
  4233. 4. Save the mask to disk in P format.
  4234.  
  4235. 5. Load the object that the mask is for again. 
  4236.  
  4237. 6. Now set the Shadowmask flag on, in the FLAGS menu and enter the name used
  4238.    to save your mask.
  4239.  
  4240. 7. Save the object in B format or test it
  4241.  
  4242. Of couse if you already have a mask designed you can skip the first 5 steps
  4243. of the list.
  4244.  
  4245.                 --------------------------------------------
  4246.  
  4247. 7.5.5 COLLISIONS.
  4248.  
  4249. The second mask is the COLLISION mask. This mask, which has nothing to do 
  4250. with the OBJECT.HIT statement which we will discuss later, determines where
  4251. the computer "senses" a collision. When the Collision mask is empty, the 
  4252. computer cannot see a collision. When you define a collision mask, the set
  4253. bits of the mask are the sensitive points.
  4254.  
  4255. You can design and install a collision mask in the same way as the Shadow 
  4256. mask. If you don't define a Collision mask, the computer will use a default
  4257. collision mask. The default mask is built by using a logic OR function on 
  4258. all the bit-planes of the bob (exactly like the shadow mask). The computer 
  4259. then reacts to contact with any set pixel of the object.
  4260.  
  4261.                                 PAGE 76
  4262.  
  4263. -----------------------------------------------------------------------------
  4264.  
  4265. In our next program we'll demonstrate other methods, other than using the
  4266. COLLISION mask for controlling collisions. Well test these statements using
  4267. two squares that move around the screen.
  4268.  
  4269.         REM 1.7.5.5 COLLISION.
  4270.         DEFINT a
  4271.         RANDOMIZE TIMER
  4272.         SCREEN 1,320,200,2,1
  4273.         WINDOW 2,,,16,1
  4274.         PRINT "Reading in Data.... "
  4275.         FOR j = 1 TO 2
  4276.             FOR i = 1 TO 13
  4277.                 READ a
  4278.                 a$(j) = a$(j)+MKI$(a)
  4279.             NEXT i
  4280.             a$(j)=a$(j)+MKI$(-1)+MKI$(-1)
  4281.             FOR i = 1 TO 30
  4282.                 a$(j) = a$(j) + MKI$(-32768&)+MKI$(1)
  4283.              NEXT
  4284.             a$(j) = a$(j) + MKI$(-1) + MKI$(-1)
  4285.         NEXT j
  4286.         FOR i = 1 TO 30
  4287.             a$(2)=a$(2)+MKI$(0)
  4288.         NEXT i
  4289.         a$(2) = a$(2) + MKI$(1)+MKI$(-32768&)
  4290.         a$(2) = a$(2) + MKI$(1)+MKI$(-32768&)
  4291.         FOR i = 1 TO 30
  4292.             a$(2) = a$(2)+MKI$(0)
  4293.         NEXT i
  4294.         CLS
  4295.         OBJECT.CLIP (70,30)-(230,190)
  4296.         LINE (70,30)-(230,190),3,b
  4297.         ON COLLISION GOSUB collroutine
  4298.         COLLISION ON
  4299.         OBJECT.SHAPE 1,a$(1)
  4300.         OBJECT.SHAPE 2,a$(2)
  4301.         OBJECT.PRIORITY 1,1
  4302.         OBJECT.HIT 1,3,2
  4303.         OBJECT.HIT 2,2,2
  4304.         OBJECT.X 1,150
  4305.         OBJECT.Y 1,80
  4306.         OBJECT.X 2,155
  4307.         OBJECT.Y 2,85
  4308.         OBJECT.VX 1,8
  4309.         OBJECT.VY 1,4
  4310.         OBJECT.START 1,2
  4311.         OBJECT.ON 1,2
  4312.         WHILE INKEY$ = ""
  4313.             LOCATE 2,15
  4314.             PRINT OBJECT.X(1);TAB(21);OBJECT.Y(1)
  4315.             PRINT TAB(15);OBJECT.X(2);TAB(21);OBJECT.Y(2)
  4316.         WEND
  4317.         WINDOW CLOSE 2
  4318.         SCREEN CLOSE 1
  4319.         END
  4320.  
  4321.                                 PAGE 77
  4322.  
  4323. -----------------------------------------------------------------------------
  4324.  
  4325.         collroutine:
  4326.             n=COLLISION(0)
  4327.             m=COLLISION(n)
  4328.         more:
  4329.             IF n=1 and m<0 THEN
  4330.                 BEEP
  4331.                 IF ABS(m) MOD 2 = 0 THEN
  4332.                     OBJECT.VX 1,(m+3)*(RND*20+1)
  4333.                 ELSE
  4334.                     OBJECT.VY 1,(m+2)*(RND*20+1)
  4335.                 END IF
  4336.             END IF
  4337.             OBJECT.VX 2, OBJECT.VX(1)+3*SGN(OBJECT.X(1)-1-OBJECT.X(2))
  4338.             OBJECT.VY 2, OBJECT.VY(1)+3*SGN(OBJECT.Y(1)-1-OBJECT.Y(2))
  4339.             OBJECT.START
  4340.             n=COLLISION(0)
  4341.             m=COLLISION(n)
  4342.             IF m<>0 THEN more
  4343.             RETURN
  4344.             DATA 0,0,0,0,0,1,0,32,0,32
  4345.             DATA 24,1,0
  4346.             DATA 0,0,0,0,0,1,0,32,0,32
  4347.             DATA 10,1,0
  4348.  
  4349. While the two squares dash around the screen, we can display their 
  4350. coordinates by using the OBJECT.X function. Or you could also display the
  4351. object's velocity using the OBJECT.VX funtion. The same function is 
  4352. available for the Y direction. These functions are very important when you 
  4353. want a program to react to a collision in a certain way.
  4354.  
  4355. In order for a collision to occur, you always need two things. In our
  4356. program we hae two objects, both objects are squares, the same size, the 
  4357. same colour, and are only a frame. Even though the objects seem similar they
  4358. have differences. Since we did not specify a collision mask for the first 
  4359. object, the computer provides a default collision mask using the OR function
  4360. on its bit-planes. The collision mask consists of only the frame of the 
  4361. object.
  4362.  
  4363. For the second object we design our own collision mask. In this mask we
  4364. set only the four centre pixels of the object. The program places the 
  4365. second object inside the first and whenever the second object tries to 
  4366. escape from the first there is a collision.
  4367.  
  4368. By using the OBJECT.CLIP statement, we confined the first object to a
  4369. specific screen area. Because of this, the first object cannot move just 
  4370. anywhere on the screen.
  4371.  
  4372. Without the COLLISION functions, we would not be able to react to a 
  4373. collision. The three COLLISION functions are the only object related 
  4374. statements that do not begin with OBJECT. The first statement, ON 
  4375. COLLISION GOSUB, tells the computer where to branch. However, this 
  4376. statement will not function without the second statement COLLISION ON, 
  4377. which tells the computer that, if there is a collision , then branch.
  4378. If COLLISION ON has not been used, the object will simply stop moving
  4379. at the border of the specified area.
  4380.  
  4381.                                 PAGE 78
  4382.  
  4383. -----------------------------------------------------------------------------
  4384.  
  4385. The third function helps us determine which two objects have collided. You
  4386. can read the first object number with COLLISION(0) and the second object
  4387. number with COLLISION(n). The n must be the number of the object that was
  4388. involved in the collision. To determine the other object involved in the
  4389. collision, substitute COLLISION(0) for the (n) in the COLLISION function.
  4390. The value that is returned is the number of the second object. A collision 
  4391. with the border will return a value smaller than one.
  4392.  
  4393.         COLLISION (COLLISION(0))        Border.
  4394.         ---------------------------------------
  4395.         -1                              top
  4396.         -2                              left
  4397.         -3                              bottom
  4398.         -4                              right
  4399.  
  4400. Sometimes it is possible for the second bob to escape from the first bob.
  4401. When the second object's speed is very fast, the collision mask can 
  4402. jump over the other object's mask without touching it. Because the border
  4403. does not affect it, the second bob can leave the defined screen area and
  4404. enclose the first object. To determine which collision will cause this
  4405. breakout use the OBJECT.HIT statement. Specify two 16-bit masks. The first
  4406. is named the MeMask and the second is named the HitMask. When two objects
  4407. collide with another, the MeMask of one is compared with the HitMask of
  4408. the other. If both masks have a one in the same position, a program 
  4409. interrupt occurs. An interrupt will also happen when an object's
  4410. HitMask is set equal to one and it collides with a window or area border
  4411. set with OBJECT.CLIP.
  4412.  
  4413. Instead of using a bit pattern, you set these masks using a number between
  4414. -32768 and +32767. The default value of these masks is -1 which means a 
  4415. full mask. The end result is an interrupt on any collision.
  4416.  
  4417. The final new statement in the program does not have a direct connection to
  4418. collisions. This statement lets you specify the sequence in which to draw
  4419. the objects on the screen. This is mostly important for deciding which
  4420. objects are to appear first. The statement is OBJECT.PRIORITY and uses
  4421. a default value of zero. The higher the priority number, the earlier an
  4422. object is drawn.
  4423.  
  4424.                                 PAGE 79
  4425.  
  4426. -----------------------------------------------------------------------------
  4427.  
  4428. 5.6 ANIMATED BIT-PLANES.
  4429.  
  4430. We have mentioned many times that the graphic information of an object is 
  4431. divided among different bit-planes. We mean that every screen pixel is made
  4432. up of many different bits in memory that determine the pixel's colour. The
  4433. depth is determined by how many bits are available for use per pixel. The
  4434. first bit of all pixels builds the first bit-plane, the second bit builds
  4435. the second plane and so-on.
  4436.  
  4437. All bit-planes are stored one after another in memory. This gives you a 
  4438. special advantage, particularly when using objects, because you can easily
  4439. add or delete a bit-plane without affecting your objects. You can also 
  4440. define objects that have less depth than the screen. For example, you could
  4441. use a screen depth of 5 and an object with a depth of two. With this depth,
  4442. your object could only have four colours but these colours can be any 4
  4443. of the screen's 32.
  4444.  
  4445. There are two statements that enable you to play with the object colour 
  4446. combinations that are possible with a palette of 32 colours. By using the 
  4447. same object from our last program we can demonstrate this.
  4448.  
  4449.         REM 1.7.5.6 OBJECT.PLANES statement
  4450.         SCREEN 1,320,200,5,1
  4451.         WINDOW 2,"Planes-Demo",,31,1
  4452.         FOR i = 1 TO 61
  4453.             READ g
  4454.             p$=p$+MKI$(g)
  4455.         NEXT i
  4456.         OBJECT.SHAPE 1,p$
  4457.         OBJECT.ON
  4458.         x=50
  4459.         y=5
  4460.         FOR  i = 0 TO 3
  4461.             FOR j = i+1 TO 4
  4462.                 IF j<>i THEN
  4463.                     FOR k = 0 TO 31
  4464.                         IF (k AND 2^i OR k AND 2^j)=0 THEN
  4465.                             OBJECT.X 1,x
  4466.                             OBJECT.y 1,y
  4467.                             OBJECT.PLANES 1,2^i+2^j,k
  4468.                             x=x+20
  4469.                             IF x>244 THEN
  4470.                                 x=50
  4471.                                 y=y+20
  4472.                             END IF
  4473.                         END IF
  4474.                     NEXT
  4475.                 END IF
  4476.             NEXT j
  4477.         NEXT i
  4478.  
  4479.                                 PAGE 80
  4480.  
  4481. -----------------------------------------------------------------------------
  4482.  
  4483.         LOCATE 22,5
  4484.         PRINT "80 different colour combinations"
  4485.         WHILE INKEY$="": WEND
  4486.         WINDOW CLOSE 2
  4487.         SCREEN CLOSE 1
  4488.         DATA 0,0,0,0,0,2,0,16,0,16,52        
  4489.         DATA 0,0,-8180,-8082,-8081,-8081,-8177
  4490.         DATA -1,-1,-1,-1,-1,-1,-1025,-1105,-681
  4491.         DATA -2049,-1,-4,-2,-1,-1,-1,-1,-1,-1,-1
  4492.         DATA -1,-16381,-16381,-16381,-16381
  4493.         DATA -16381,-16381,-4,-2,-1,-1,-1,-1,-1
  4494.         DATA -1,-1,-1,-1,-1025,-1105,-681,-2049
  4495.         DATA -1
  4496.  
  4497. As you can see, there are 80 possible combinations. We will explain why
  4498. there is only 80 later on. First we want to show you how to achieve these
  4499. combinations. There are two values in the object structure that make this
  4500. possible. The first value tells us what bit-plane is being written to. The
  4501. bit-plane determines the order of the five bits of a pixel and also the 
  4502. colour in which it appears. The value is named PlanePick and you will find
  4503. it in our editor under the FLAGS menu.
  4504.  
  4505. There are tem possible combinations for a two depth bob, in a screen with a 
  4506. depth of five:
  4507.  
  4508.         1.        11000        0,1,2,3
  4509.         2.        10100        0,1,4,5
  4510.         3.        10010        0,1,8,9        
  4511.         4.        10001        0,1,16,17
  4512.         5.        01100        0,2,4,5
  4513.         6.        01010        0,2,8,9
  4514.         7.        01001        0,2,16,17
  4515.         8,        00110        0,4,8,9
  4516.         9.        00101        0,4,16,17
  4517.         10.       00011        0,8,16,17
  4518.  
  4519. After each of the ten combinations we have listed the colour registers that
  4520. the computer uses when you write to other bit-planes. In the number series
  4521. made up of ones and zeros, a one means that a plane will be written in that
  4522. bit-plane. The first plane of an object will be the first selected plane 
  4523. of the screen. PlanePick is not limited to spreading two planes over five
  4524. bit-planes. It works just as well with fewe or more planes.
  4525.  
  4526. As explained above, our editor determines the selected plane through a 
  4527. series of ones and zeros. When you checked the menus for PlanePick you
  4528. probably got an idea about the second method for changing colours. Directly
  4529. under PlanePick in the menus is the statement PlaneOnOff.
  4530.  
  4531.  
  4532.                                 PAGE 81
  4533.  
  4534. -----------------------------------------------------------------------------
  4535.  
  4536. This statement sets a value in the object structure that determines what 
  4537. happens in the unselected screen planes. All planes not used by PlanePick 
  4538. are considered unusud. As the name indicates you use PlaneOnOff to turn 
  4539. planes on and off. You already know about the off status since this is the
  4540. normal condition for an unused plane. When you switch on a bob in an unused
  4541. plane a shadow mask is written to that plane. In other words, when a 
  4542. bit-plane is set to on, and the shadow mask contains a matching bit for a 
  4543. pixel, that pixel's colour will change.
  4544.  
  4545. The construction of PlaneOnOff is the same as PlanePick. Unlike the flags,
  4546. the value assigned using the editor can be changed later, otherwise our 
  4547. colour combination program would be more complicated. We use the 
  4548. OBJECT.PLANES to set both of these values. This is the sequence you pas
  4549. the values: object number, PlanePick and PlaneOnOff. Again, you cannot 
  4550. simply enter the binary number sequence, you have to calculate the 
  4551. values. The following formula does this:
  4552.  
  4553.         PlanePick = b1+2*b2+4*b3+8*b4+16*b5
  4554.  
  4555. All you have to do is replace b1 thru b5 with the converted binary sequence.
  4556. The formula for PlaneOnOff is the same.
  4557.  
  4558. PlanePick and especially PlaneOnOff, open up unexpected methods for 
  4559. animation. From one bob you can create many different figures. Using this 
  4560. method we have created an olympic torch on the screen. The flickering 
  4561. flame and different colours are created by changing PlanePick and 
  4562. PlaneOnOff.
  4563.         
  4564.         REM 1.7.5.6B Fire
  4565.         DEF FNplanes=CINT(RND)*4+CINT(RND)*8+CINT(RND)*16
  4566.         FOR i = 1 TO 274
  4567.         READ a
  4568.         a$=a$+MKI$(a)
  4569.         NEXT i
  4570.         SCREEN 1,320,200,5,1
  4571.         WINDOW 2,,,,1
  4572.         PALETTE 0,0,0,0
  4573.         PALETTE 4,1,.5,0
  4574.         PALETTE 8,1,0,0
  4575.         PALETTE 12,1,.26,0
  4576.         PALETTE 16,1,.4,0
  4577.         PALETTE 20,.8,0,0
  4578.         PALETTE 24,.95,.5,0
  4579.         PALETTE 28,1,.9,0
  4580.         LOCATE 2,5
  4581.         PRINT "The Eternal Flame"
  4582.         LINE (96,120)-(110,180),26,bf
  4583.         CIRCLE (103,70),60,27,4.02,5.4
  4584.         LINE (66,108)-(140,108),27
  4585.         OBJECT.SHAPE 1,a$
  4586.  
  4587.  
  4588.                                 PAGE 82
  4589.  
  4590. -----------------------------------------------------------------------------
  4591.  
  4592.         CLOSE 1
  4593.         OBJECT.X 1,79
  4594.         OBJECT.Y 1,79
  4595.         OJECT.ON 1
  4596.         fire:
  4597.           a=FNplanes
  4598.           IF a = 28 THEN a = 24
  4599.           OBJECT.PLANES 1,a
  4600.           FOR i = 0 TO 10: NEXT
  4601.           OBJECT.PLANES 1,,FNplanes
  4602.           FOR i=0 TO 10: NEXT
  4603.           GOTO fire:
  4604.  
  4605.         REM flame DATA
  4606.         DATA 0,0,0,0,0,2,0,48,0,29
  4607.         DATA  12,24,0,0,0,0,0,0,0,0
  4608.         DATA 0,0,0,0
  4609.         DATA 0,0,0,0,0,0,0,0,0,0
  4610.         DATA 0,0,0,0,0,0,0,96,0,0
  4611.         DATA 0,0,0,1152,16384,0,1665,-16384,32,1792
  4612.         DATA -16384,16,1671,-32768,48,902,0,18,5661,-32768
  4613.         DATA 26,-30194,128,12,-20869,256,7,-14609,-13824,3
  4614.         DATA 15999,-15872,0,-257,-17664,0,-1554,23040,0,-7434
  4615.         DATA -8704,0,-18441,5120,0,27399,18432,0,30230,16384
  4616.         DATA 0,29704,16384,0,-32752,0,0,0,0,0
  4617.         DATA 0,0,0,0
  4618.         DATA 0,0,192,0,0,320,0,0,320,128
  4619.         DATA 0,480,1920,0,416,7680,256,1888,16128,896
  4620.         DATA 1664,-1024,896,16353,-9216,992,-16607,-208,976,-20702
  4621.         DATA -2044,504,32727,26652,404,8013,26728,252,4991,29040
  4622.         DATA 210,15420,31728,122,-21928,-3088,77,-21544,16128,46
  4623.         DATA 8360,8896,50,56,960,10,-32176,8384,10,-16384
  4624.         DATA -32640,6,12,-24320,5,271,8192,2,-31244,-32768
  4625.         DATA 0,-32657,-26624,0,-32745,12288,0,0,8192,0
  4626.         DATA 2,0,0,6
  4627.         DATA 0,0,6,0,0,7,0,0,3,0
  4628.         DATA 0,9,0,0,11,256,0,10,768,1
  4629.         DATA 28,3328,1,26,4608,2,62,8704,2,206
  4630.         DATA 8704,6,460,30208,6,460,28160,15,510,17920
  4631.         DATA 31,3486,-31744,4,-27235,19968,20,21022,19456,5
  4632.         DATA 13132,7168,21,-26168,12288,7,-25524,-4096,1,22590
  4633.         DATA 28672,2,-10628,20480,3,-3279,0,1,29903,-20480
  4634.         DATA 0,19525,12288,0,11577,0,0,1033,0,0,11777,0
  4635.  
  4636.                                 PAGE 83
  4637.  
  4638. -----------------------------------------------------------------------------
  4639.  
  4640. Our flame uses only eight different colors that come from registers 0,4,8,
  4641. 12,16,20,24 and 28. These are the only colours changed, all others are free
  4642. for use.
  4643.  
  4644. It is possible for the flame to have multiple combinations of the two planes
  4645. and the shadow mask. PlanePick could select both planes at the same time. It
  4646. is also possible that only one, or none, of the planes will be drawn. 
  4647. PlaneOnOff can also set unused planes on.
  4648.  
  4649. All of this is arranged with very little effort. These methods can be 
  4650. applied to many different types of objects. For example, an exploding 
  4651. spaceship, the winking of an eye or lip movement, and much more can be 
  4652. packed into an object.
  4653.  
  4654.                                 PAGE 84
  4655.  
  4656. -----------------------------------------------------------------------------
  4657.  
  4658. 1.7.6 THE ALTERNATIVE : SPRITES.
  4659.  
  4660. We have not said much about sprites so far in our discussions of animation.
  4661. Sprites are controlled in a similar way that bobs are controlled. The
  4662. same BASIC statements that apply to bobs also apply to sprites.
  4663.  
  4664.                 -----------------------------------------------
  4665.  
  4666. 1.7.6.1 THE SMALL DIFFERENCE.
  4667.  
  4668. To design a sprite with our editor all you have to do is set the sprite flag
  4669. in the FLAG menu. When you do this all the other menu items will become 
  4670. ghost selections. You will not be able to use them because they have no 
  4671. effect on sprites. Sprite characteristics are determined by the settings of
  4672. the OverLay and SaveBack flags.
  4673.  
  4674. The properties of sprites are very specific. A sprite can never be more than
  4675. 16 pixels wide and can only have three colours. The height is not limited.
  4676. Sprites can move much faster than BOBS.
  4677.  
  4678.                 -----------------------------------------------------
  4679.  
  4680. 1.7.6.2 COLOUR AND SPRITES.
  4681.  
  4682. In contrast with bobs, a sprites' colour has no direct connection to the 
  4683. screen depth. Sprites carry their own colour information which is not 
  4684. stored in any registers (there are no more than 35 possible colours).
  4685. The colours carried by as sprite can affect the screen colours that are
  4686. covered by it. When a sprite is on top of or behind a pixel, the colour
  4687. register for that pixel will cause a color change.
  4688.  
  4689. You cannot chose which register a sprite stores its colours. However, you
  4690. can choose which colours the sprite uses. When you have the sprite flag set
  4691. you can select "spr.color" from the menu to pick three colours for the 
  4692. sprite. The values are assigned the same way as with PALETTE>
  4693.  
  4694.                                PAGE 85
  4695.  
  4696. ----------------------------------------------------------------------------------------------------------------------------------------------------------
  4697.  
  4698.                     CHAPTER 2 - AMIGA OPERATING SYSTEM
  4699.  
  4700. So far our programs have worked well using only the everyday BASIC
  4701. statements. However, at this point BASIC alone is not enough. Our next
  4702. series of projects requires capabilities that BASIC cannot provide. These
  4703. capabilities include a graphic hardcopy routine, new character sets,
  4704. 1024*1024 pixel superbitmap graphics, and much more.
  4705.  
  4706. With most computers you would have to write machine language programs in
  4707. order to perform additional functions and statements. This is not required
  4708. with the Amiga because the solutions for our next projects are resident in
  4709. the Amiga operating system and the Amiga operating system libraries. Each
  4710. library consists of hundreds of small machine language routines. These
  4711. routines are organised by functions and can handle just about any
  4712. operation. So, with the Amiga, you do not have to create new commands, you
  4713. only have to learn how to use the libraries.
  4714.  
  4715. The procedure for accessing libraries is built into AmigaBASIC, the
  4716. statements "LIBRARY" and "DECLARE FUNCTION (.....) LIBRARY" are used to
  4717. access the libraries. In order to access these libraries we use a .bmap
  4718. file. For every system library, you create a matching .bmap file which
  4719. contains the names of all machine language library routines and other
  4720. necessary parameters. By using the ConvertFD program on the extra disk, you
  4721. can quickly create all the required .bmap files. See the ABOUTBMAPS program
  4722. on your extras disk for more information on creating the .bmap files.
  4723.  
  4724. Before you read any further, you should generate the following ".bmap"
  4725. files:
  4726.  
  4727.         .bmap files
  4728.         --------------------
  4729.         graphics.bmap
  4730.         exec.bmap
  4731.         layers.bmap
  4732.         intuition.bmap
  4733.         diskfont.bmap
  4734.         dos.bmap
  4735.  
  4736. You should copy these files to your LIBS directory on the Workbench disk.
  4737. You can also use these files by having them and your program files in one
  4738. directory on the same disk.
  4739.  
  4740.                                 PAGE 87
  4741.  
  4742. ----------------------------------------------------------------------------
  4743.  
  4744. Now that we have finished the groundwork we can move onto the programming.
  4745. The LIBRARY and DECLARE FUNCTION (....) LIBRARY statements are our tools.
  4746. Before you can use one (or more) of the system libraries, you have to open
  4747. them. We use the LIBRARY statement to do this:
  4748.  
  4749.         LIBRARY "graphics.library"
  4750.  
  4751. When AmigaBASIC receives this command, BASIC looks for the definition file
  4752. graphics.bmap. If this file is not found in the current directory, BASIC
  4753. will look for it on the Workbench disk in the LIBS directory. When BASIC
  4754. doesnt find the .bmap file there, you will get a "file not found" error. As
  4755. you can see, in order to run your program, it is important that the .bmap
  4756. file is available.
  4757.  
  4758. When basic finds the .bmap file, it opens the appropriate system library.
  4759. From this point on, BASIC will compare the program function calls with the
  4760. graphics.bmap function list. The requested routines are executed from the
  4761. library when they are called.
  4762.  
  4763. The next program is a small deminstration of how this works. The function
  4764. we want to use is in the graphics.library and is called TEXT. This routine
  4765. prints a text string of any length on the screen. There are three required
  4766. parameters:
  4767.  
  4768.         1.) The address of the RastPort (to be discussed shortly)
  4769.         2.) the address of the text.
  4770.         3.) the length of the text.
  4771.  
  4772.         REM 2a. Hello World.
  4773.         LIBRARY "graphics.library"
  4774.         a$="Hello World!"       
  4775.         length% = LEN(a$)
  4776.         rastport& = WINDOW(8)
  4777.         CALL Text(rastport&,SADD(a$),length%)
  4778.         LIBRARY CLOSE
  4779.  
  4780. Enter this program very carefully because system libraries are very
  4781. sensitive to errors. When the program starts, it will look for the
  4782. graphics.bmap file. In a few moments the message, "Hello World!" will
  4783. appear in the upper left hand corner of the screen. The statement LIBRARY
  4784. CLOSE closes the library, but it is not required because BASIC will
  4785. automatically close any open libraries any time you use the RUN or NEW.
  4786.  
  4787. We like to explain the statement SADD(a$) and the variable rastport& used
  4788. in the above program. The statement SADD passes the memory address of the
  4789. of the text string a$. The TEXT routine then uses this address to read the
  4790. text. RastPort indicates which drawing plane tO use.
  4791.  
  4792.                                 PAGE 88
  4793.  
  4794. ----------------------------------------------------------------------------
  4795.  
  4796. We will explain this in more detail later. What you need to understand now
  4797. is that the RastPort address tells the computer the window in which to
  4798. display the text. The actual window address is in the variable WINDOW(8).
  4799.  
  4800. The above program only demonstrated how to use a library. You could have
  4801. easily accomplished the same thing with a normal PRINT statement. The next
  4802. program has a SUB routine named "p" that uses the TEXT routine and is
  4803. simply a faster replacement for PRINT. To call it:
  4804.  
  4805.         P "text",mode%
  4806.               mode%     0 = PRINT "text";
  4807.                         1 = PRINT "text"
  4808.  
  4809.         '##########################################
  4810.         '#
  4811.         '# Program: Quick Print.
  4812.         '# Date   : 04/13/87
  4813.         '# Author : tob
  4814.         '# Version: 1.0
  4815.         '#
  4816.         '##########################################
  4817.  
  4818.         PRINT "Searching for the .bmap file ..."
  4819.         'GRAPHICS-LIBRARY
  4820.         'Text()
  4821.         LIBRARY "graphics.library"
  4822.         demo:   demo$=STRING$(80,"*")
  4823.                 CLS
  4824.                 '* Quick print.
  4825.                 PRINT "QUICK PRINT:"
  4826.                 FOR loop1%=0 TO 10
  4827.                    P demo$,1
  4828.                 NEXT loop1%
  4829.                 '* Normal Print
  4830.                 PRINT "AmigaBASIC's normal PRINT:"
  4831.                 FOR loop2% = 0 TO 10
  4832.                    PRINT demo$
  4833.                 NEXT loop2%
  4834.                 LIBRARY CLOSE
  4835.         SUB P(was$,mode%) STATIC
  4836.                 CALL Text(WINDOW(8),SADD(was$),LEN(was$))
  4837.                 IF mode% = 1 THEN PRINT
  4838.         END SUB
  4839.  
  4840. This new routine is three times as fast as PRINT. The text appears
  4841. immediately, not line by line. If you add an LPRINT to the SUB P routine,
  4842. much more is possible. You could PRINT and LPRINT all text without using an
  4843. LPRINT after each print in your program.
  4844.  
  4845. We are finished with our first useful application of the system libraries.
  4846. Hopefully, you are now curious about the many other possibilities.
  4847.  
  4848.                                 PAGE 89
  4849.  
  4850. -----------------------------------------------------------------------------
  4851.  
  4852. Our introduction is not quite complete because the DECLARE FUNCTION (....)
  4853. LIBRARY statement was not included in our demonstration program. The TEXT
  4854. routine uses a CALL statement since the libraries performed any required
  4855. actions without having to return a result to BASIC; therefore a DECLARE
  4856. statement was not needed. Functions that have to return a result to BASIC
  4857. must use the DECLARE statement. For example, one of these functions from
  4858. the graphic library is READPIXEL. READPIXEL requires several parameters:
  4859. the address of the RastPort (a pointer to the desired window), and a X and
  4860. Y coordinate. The value that is returned to the program by READPIXEL is the
  4861. colour of the specified pixel. To use this function you must use the
  4862. DECLARE statement:
  4863.  
  4864.         REM 2c DECLARE
  4865.         DECLARE FUNCTION ReadPixel% LIBRARY
  4866.         LIBRARY "graphics.library"
  4867.         x%=320
  4868.         y%=125
  4869.         rastport&=WINDOW(8)
  4870.         colour% = ReadPixel%(rastport&,x%,y%)
  4871.         PRINT "Found Colour Number";colour%
  4872.         LIBRARY CLOSE
  4873.  
  4874. ReadPixel is declared as a function in the first program line because, when
  4875. called, it returns a value to the program. The "%" character ater READPIXEL
  4876. in the function definition, declares the value returned by READPIXEL to be
  4877. of type integer. From this point on, the routine is called using the name
  4878. READPIXEL%.
  4879.  
  4880. This completes our explanation of the basic principles involved in using
  4881. libraries. You know how to open a library and how to access a routine in
  4882. it. The following pages provide details on what routines the various
  4883. libraries have and what parameters are required. AmigaBASIC can open and
  4884. access up to 5 libraries at the same time. You should always remember that
  4885. the routines in these libraries are machine language programs. Even though
  4886. they are a bit more difficult to use, these routines are much faster than
  4887. pure BASIC. Also remember that these routines do not check for incorrect or
  4888. invalid parameters, so one small mistake, an invalid parameter or a wrong
  4889. call can cause the system to crash. You would then have to reboot from the
  4890. Workbench and all programs in memory are lost.
  4891.  
  4892. Enter all your programs carefully and save them to disk before you test
  4893. them.
  4894.  
  4895. The following program IBRARY "graphics.library"
  4896.         a$="Hello World!"
  4897.         length% = LEN(a$)
  4898.         rasport& = WINDOW(8)
  4899.  
  4900.         '* Above is the error (rasport& instead of
  4901.         '* rastport& so rastport& = 0
  4902.  
  4903.         CALL Text(rastport&,SADD(a$),length%)
  4904.         LIBRARY CLOSE
  4905.  
  4906. If you run this program you will receive the following message or the
  4907. system will lock up completely:
  4908.  
  4909.         Software failure. Click left mouse button to continue.
  4910.            Guru Meditation #00000004.00xxxxx
  4911.  
  4912. Follow the instructions, or perform a warm reset by pressing both <A> Amiga
  4913. keys and the <Ctrl> key at the same time.
  4914.  
  4915.                                 PAGE 91
  4916.  
  4917. -----------------------------------------------------------------------------
  4918.                 Now load part 2
  4919. -----------------------------------------------------------------------------
  4920.  
  4921.